我有大约10 numpy
个n
项目数组。全局标识为i
的OpenCL工作程序仅查看每个数组的i
元素。我该如何安排记忆?
我在考虑在显卡上交错数组,但我不确定这是否会有任何性能提升,因为我不了解工作组内存访问模式。
答案 0 :(得分:1)
我不熟悉numpy,但是如果:
i
的主题查看i
元素(如您所述)由于合并的内存访问,您应该能够实现最佳的内存吞吐量。在这种情况下,交错不会带来任何性能提升。
如果未满足最后两点之一,并且您可以通过交错实现它们,则可以看到性能提升。
编辑:阵列结构(SoA)与结构阵列(AoS)
这一点可以在文献中找到。我会做的很简短:
为什么SoA优于AoS?想象一下,你有10个32位数据类型的数组。 AoS解决方案如下:
struct Data
{
float a0;
float a1;
...
float a9;
}; // 10 x 32bit = 320 bit
struct Data array[512];
内存读取怎么样?内存不对齐而没有任何更改,内存传输无法合并。但是,需要阅读的代码很短:
Data a = array[i];
幸运的是,编译器足够智能,至少可以合并一些读取指令。一个选项是显式内存对齐。这将使您的全局内存消失,这在GPU上非常有限。
现在的SoA解决方案:
struct Data
{
float a0[512];
float a1[512];
...
float a9[512];
};
struct Data array;
访问内存的工作稍微复杂一些,但是每次访问都可以在合并读取中组合,并且不需要内存对齐。您也可以忘记结构并使用每个数组,而不会出现任何性能问题。
可以使用的另一件事是矢量化数据类型(如果你的numpy数组允许这样)。您可以使用float2,float4(或其他简单数据类型,如int,double ...)来利用组合内存传输,即每次读取float4数组都会在128位内存传输中合并,从而最大限度地提高内存吞吐量。