2
\$\begingroup\$

First thing is that I know how to give values to uniforms in OpenGL. Second thing is that it is a question related to optimization and performance.

The habit for changing the uniforms, we preferred is like this:

//Consider that we have shaders having 'aValue' as uniform

//During initialization
GLint loc = glGetUniformLocation(program, "aValue");

//During a loop or when required to change uniform's value
if (loc != -1)
{
   glUniform1f(loc, 0.75);
}

But what if it is like this:

//'program' is a global variable

//Can be anywhere but not after destructing 'program'
void updateUniformf( const char* name, float value )
{
    glUniform1f(glGetUniformLocation(program, name), value);
}

//During a loop or when required to change uniform's value
updateUniformf("aValue", 0.75);

How much would such approach decreases the performance? Or would this approach even affects the performance? It will be appreciable to have some measurements or practical example rather than all theories. Of course, I need to know reasons as well.

Thanks for answering this question!

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Rules of thumb:

  • Keep communications with the GPU at a minimum
  • String comparisons are not known to be especially fast

Here are my test results:

  • At 10000 uniforms per frame set using a pre-located uniform ID (as many characters as you need), we get 554 FPS on average.
  • At 10000 uniforms per frame, with the uniform ID being looked up each time (7 characters), we get 227 FPS.
  • At 10000 uniforms per frame, with the uniform ID being looked up each time (119 characters), we get only 99 FPS.

Bear in mind that the hardware components can affect these results significantly but the trend itself shouldn't change much.

tldr;

Always look up uniform locations once, at the beginning and then use those integral IDs to set the values. Do not look them up each time! String comparisons are not cheap.

\$\endgroup\$
13
  • 1
    \$\begingroup\$ It's kinda hard to imaging a driver would use anything but a std::map in user memory for use in glGetUniformLocation \$\endgroup\$ Commented Nov 20, 2015 at 8:57
  • \$\begingroup\$ As pointed out above you are hardly communicating with GPU when fetching locations - it should be rather: Rule of thumb: string comparisons are not known to be especially fast. \$\endgroup\$
    – wondra
    Commented Nov 20, 2015 at 10:52
  • \$\begingroup\$ OK @wondra ... This is what we can say, 'hardly communicating'. What if this is for 1000 objects? Will this be the same case. Also, I am not a great programmer; I don't know much about hash maps. But I got the concept: Update the uniform only when the value gets a change! If I misunderstood, please correct me! \$\endgroup\$ Commented Nov 20, 2015 at 13:26
  • \$\begingroup\$ I still don't get fine explanation! The question is: How much will performance be affected if we get the location of a particular uniform every time when we want to update the uniform instead of getting the location once and then, using that to update the uniforms? Take that scenario as an example: Updating 100 uniform per frame. \$\endgroup\$ Commented Nov 20, 2015 at 13:35
  • 1
    \$\begingroup\$ Measurements should be in milliseconds. \$\endgroup\$ Commented Nov 21, 2015 at 21:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .