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

Reply via email to