On Mon, May 5, 2014 at 5:37 AM, Chia-I Wu <[email protected]> wrote:
> On Sat, May 3, 2014 at 1:59 AM, Ian Romanick <[email protected]> wrote:
>> On 04/22/2014 01:58 AM, Chia-I Wu wrote:
>>> From: Chia-I Wu <[email protected]>
>>>
>>> Threaded glCompileShader can be enabled for a context by calling
>>> _mesa_enable_glsl_threadpool. It will initialize the singleton GLSL thread
>>> pool and defer glCompileShader calls to the thread pool.
>>>
>>> For applications to benefit from threaded glCompileShader, they have to
>>> compile shaders in this fashion
>>>
>>> for (i = 0; i < num_shaders; i++)
>>> glCompileShader(shaders[i]);
>>> for (i = 0; i < num_shaders; i++)
>>> glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &val);
>>
>> I think when you try this series on some real applications, you will be
>> disappointed. Eric had a pretty similar branch
>> (http://cgit.freedesktop.org/~anholt/mesa/log/?h=compiler-threads), but
>> it saw no benefit on any applications... because everybody does
>>
>> for (i = 0; i < num_shaders; i++) {
>> glCompileShader(shaders[i]);
>> glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &val);
>> }
>>
>> or
>>
>> for (i = 0; i < num_shaders; i++) {
>> glCompileShader(shaders[i]);
>> glAttachShader(prog, shaders[i]);
>> }
>>
>> glLinkProgram(prog);
> Yeah, I am aware of the situation with real-world applications. Only
> applications that are modified to not immediately check compilation results
> will get the speed up in compile times. That is why this feature needs to be
> enabled through drirc. We, at LunarG, are working with major game engines
> vendors to ensure this performance benefit is realized.
>
>> I'm also curious about your test case... did you link the shaders? As
>> far as I'm aware, the bulk of time spent in the compiler happens during
>> linking (final optimizations and register allocation). Eric's data
>> (http://lists.freedesktop.org/archives/mesa-dev/2014-April/057494.html)
>> says we spend more than 2x time in linking than in compiling.
> No, I did not. In my other experiment with Unigine Tropics, the
> distribution of time was more like
>
> glCompileShader: 50%
> glLinkProgram FE: 25%
> glLinkProgram BE: 25%
I've rerun the test (source attached). The numbers from compiling and
linking Unigine Tropics shaders are
_mesa_CompileShader: 54.8%
link_shaders: 17.1%
brw_link_shaders: 27.9%
The numbers from running on another set of shaders (took about 100 seconds) are
_mesa_CompileShader: 50.4%
link_shaders: 5.6%
brw_link_shaders: 43.8%
--
[email protected]
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/freeglut_ext.h>
#define MAX_PROGRAMS 4100
struct {
GLuint prog;
long long prog_time;
long long shader_times[2];
} progs[MAX_PROGRAMS];
static GLuint create_shader(int id, GLenum type)
{
char filename[32];
size_t size;
FILE *fp;
char *buf;
GLuint sh;
switch (type) {
case GL_VERTEX_SHADER:
snprintf(filename, sizeof(filename), "%d.vert", id);
break;
case GL_FRAGMENT_SHADER:
snprintf(filename, sizeof(filename), "%d.frag", id);
break;
default:
return 0;
break;
}
fp = fopen(filename, "rb");
if (!fp)
return 0;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
if (!size) {
fclose(fp);
return 0;
}
fseek(fp, 0, SEEK_SET);
buf = malloc(size + 1);
if (!buf) {
fclose(fp);
return 0;
}
if (fread(buf, 1, size, fp) != size) {
printf("error reading %s\n", filename);
fclose(fp);
return 0;
}
buf[size] = '\0';
fclose(fp);
sh = glCreateShader(type);
glShaderSource(sh, 1, (void*)&buf, NULL);
return sh;
}
static void compile_all_shaders(void)
{
struct timeval start, end;
GLint val;
int i;
for (i = 0; i < MAX_PROGRAMS; i++) {
GLuint prog;
int num_shaders, j;
prog = glCreateProgram();
num_shaders = 0;
for (j = 0; j < 2; j++) {
GLenum type = (j == 0) ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;
GLuint sh;
sh = create_shader(i, type);
if (!sh)
continue;
num_shaders++;
gettimeofday(&start, NULL);
glCompileShader(sh);
gettimeofday(&end, NULL);
glGetShaderiv(sh, GL_COMPILE_STATUS, &val);
if (!val) {
char buf[1024];
GLsizei len;
glGetShaderInfoLog(sh, sizeof(buf), &len, buf);
printf("%d.%d: %*s\n", i, j, len, buf);
}
progs[i].shader_times[j] = 1000000ll * (end.tv_sec - start.tv_sec) +
((long long) end.tv_usec - start.tv_usec);
glAttachShader(prog, sh);
glDeleteShader(sh);
}
if (num_shaders < j) {
if (num_shaders) {
;//glProgramParameteri(prog, GL_PROGRAM_SEPARABLE, GL_TRUE);
}
else {
glDeleteProgram(prog);
continue;
}
}
gettimeofday(&start, NULL);
glLinkProgram(prog);
gettimeofday(&end, NULL);
glGetProgramiv(prog, GL_LINK_STATUS, &val);
if (!val) {
char buf[1024];
GLsizei len;
glGetProgramInfoLog(prog, sizeof(buf), &len, buf);
printf("%d: %*s\n", i, len, buf);
}
progs[i].prog = prog;
progs[i].prog_time = 1000000ll * (end.tv_sec - start.tv_sec) +
((long long) end.tv_usec - start.tv_usec);
}
}
static void delete_all_shaders(void)
{
int i;
for (i = 0; i < MAX_PROGRAMS; i++)
glDeleteProgram(progs[i].prog);
}
static void print_times(void)
{
long long prog = 0, vs = 0, fs = 0;
int i;
for (i = 0; i < MAX_PROGRAMS; i++) {
prog += progs[i].prog_time;
vs += progs[i].shader_times[0];
fs += progs[i].shader_times[1];
}
printf("glLinkProgram took %.3fs\n", (double) prog / 1000000.0);
printf("glCompileShader(vs) took %.3fs\n", (double) vs / 1000000.0);
printf("glCompileShader(fs) took %.3fs\n", (double) fs / 1000000.0);
}
int main(int argc, char **argv)
{
GLenum type;
glutInit(&argc, argv);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
type = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE;
glutInitDisplayMode(type);
glutCreateWindow(*argv);
printf("GL_VERSION = %s\n", glGetString(GL_VERSION));
glewInit();
compile_all_shaders();
print_times();
delete_all_shaders();
return 0;
}
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev