全局变量的顺序会改变C /OpenGL的性能

Order of global variables changes performance in C++/OpenGL

本文关键字:OpenGL 性能 改变 顺序 全局变量      更新时间:2023-10-16

我使用了一个多线程代码(Windows),使用pthread用于C 中的线程。

我有4个线程分裂一个作业,以便每个作业都访问一个大型全局数组的1/4。

如果我在全局范围声明部分的特定点上定义了全局范围中数组的指针,我发现我可以获得2倍的性能降低 - 似乎我的全局声明的顺序似乎对我的应用程序性能。

有人知道为什么吗?

这是我的结果:

  • 单线= 0.07秒
  • 4个线程= 0.02秒(当全局指向大型数组时全球声明的开始)
  • 4个螺纹= 0.04秒(当全局指向大型数组的指针为在全球声明的中间)

如果重要的话,我在全球范围中声明的指针是:

glbyte* render_flag;glfloat* surface_primative;

正确地指出,我应该评论说,这些测试的精度很高,可能是2个重要数字,但它们高度一致。

是否有人会根据以前的全球声明顺序遇到绩效差异?还是有人知道为什么这在理论上可能会发生?

附加:

我已经注意到(感谢SO的建议),我的线程使用的数组声明直接在(内存空间中)旁边(在内存空间中),这些变量也由线程修改:

int number_of_tiles;        
int success_count_1;   ///Counters for successful searches
int success_count_2;
int success_count_3;
int success_count_4;
int offset;   
GLbyte* render_flag;   ///Pointer to array of render flags
GLfloat* surface_primative;   ///Pointer to surface primative array

如果我在阵列的指针之间包括一些填充物,而我的代码再次运行的计数器再次运行:

int number_of_tiles;        
int success_count_1;   ///Counters for successful searches
int success_count_2;
int success_count_3;
int success_count_4;
int offset;
char padding[100];   
GLbyte* render_flag;   ///Pointer to array of render flags
GLfloat* surface_primative;   ///Pointer to surface primative array

正如Art在评论中所暗示的那样,我想您可能最终会出现错误共享,即数据共享缓存线和线程/内核无法有效地工作。

您需要将每个线程写入的数据保持公平(64至256个字节左右),以在使用多个线程时获得良好的效率。

您的数据访问/写入模式如何显示指针和数据?

update

我不是专家,但可能是1/4距离Modulo Cache-line大小可以使线程相互干扰。Cache Associativiy试图减轻这种情况,但仍然如此。

另一个问题是,如果这些指针附近的数据正在不断更新。

像英特尔的Vtune一样,一个好的参考器应该有助于诊断。

至于行为,我会根据您的重新订购内容来探讨数据以分配不同地址。指针周围的数据看起来如何?

我认为减轻这是通过分配比您需要的多略多的内存并在合适的n bytes边界上对齐块来完成的。如果问题不是数据,而是指示器,则可以在64个字节边界上对齐,或将它们的本地副本保留在每个线程中。

再次,我知道英特尔(在他们的IPP库中)有一个特定的STL分配器来部分帮助。阅读应该对您有所帮助。

文章"避免和识别错误共享"是一个开始,有一些附加的指针(heh;)。