OpenCL性能:使用原语数组与结构数组

OpenCL性能:使用原语数组与结构数组,opencl,Opencl,我试图在一个内核中使用几个长度相同的double数组。我知道我可以在.cl文件中定义一个包含多个double的结构,而不是将每个double*作为单独的参数传递给内核,然后将一个指针传递给结构数组 这两种方式的性能会有所不同吗?如果我错了,请纠正我,但我认为传递单个双指针意味着可以合并访问。访问结构也会合并吗?只要你的结构不包含任何指针,你所说的是绝对可能的。正如您已经考虑过的,主要影响通常是它对合并内存操作的影响。影响有多大取决于内存访问模式、结构的大小和运行的设备。需要更多的细节来更全面地描

我试图在一个内核中使用几个长度相同的double数组。我知道我可以在.cl文件中定义一个包含多个double的结构,而不是将每个double*作为单独的参数传递给内核,然后将一个指针传递给结构数组


这两种方式的性能会有所不同吗?如果我错了,请纠正我,但我认为传递单个双指针意味着可以合并访问。访问结构也会合并吗?

只要你的结构不包含任何指针,你所说的是绝对可能的。正如您已经考虑过的,主要影响通常是它对合并内存操作的影响。影响有多大取决于内存访问模式、结构的大小和运行的设备。需要更多的细节来更全面地描述这一点

也就是说,我以这种方式非常成功地使用了struct的一个实例是,正在读取的元素对于工作组中的所有工作项都是相同的。在这种情况下,我的硬件(nvidia GTX 570)不会受到处罚。此外,值得记住的是,在某些情况下,序列化的内存操作所增加的延迟可能会被隐藏。在CUDA世界中,这将通过对具有高算术强度的问题具有高占用率来实现


最后值得指出的是,使用结构的语义清晰性本身就有好处。你必须考虑到你的特定问题的任何性能成本。我的建议是试试看;提前预测这些问题的影响是非常困难的。

只要你的结构不包含任何指针,你所说的绝对可能。正如您已经考虑过的,主要影响通常是它对合并内存操作的影响。影响有多大取决于内存访问模式、结构的大小和运行的设备。需要更多的细节来更全面地描述这一点

也就是说,我以这种方式非常成功地使用了struct的一个实例是,正在读取的元素对于工作组中的所有工作项都是相同的。在这种情况下,我的硬件(nvidia GTX 570)不会受到处罚。此外,值得记住的是,在某些情况下,序列化的内存操作所增加的延迟可能会被隐藏。在CUDA世界中,这将通过对具有高算术强度的问题具有高占用率来实现


最后值得指出的是,使用结构的语义清晰性本身就有好处。你必须考虑到你的特定问题的任何性能成本。我的建议是试试看;很难提前预测这些问题的影响。

结构和单个元件将具有完全相同的性能。 假设你有一个大的双倍数组,第一个工作项使用0,100,200,300。。。下一个使用101201301

如果有一个100倍的结构,在内存中第一个结构将是第一个(0-99),然后是第二个(100-199),依此类推。内核将访问完全相同的内存和相同的位置,唯一的区别是如何定义内存抽象


在具有不同元素类型(char、int、double、bool等)的结构的更一般的情况下,可能会发生aligment不是一个数据数组的情况。但它仍将是“半联合的”。我甚至打赌性能仍然是一样的。

结构和单个元素将具有完全相同的性能。 假设你有一个大的双倍数组,第一个工作项使用0,100,200,300。。。下一个使用101201301

如果有一个100倍的结构,在内存中第一个结构将是第一个(0-99),然后是第二个(100-199),依此类推。内核将访问完全相同的内存和相同的位置,唯一的区别是如何定义内存抽象


在具有不同元素类型(char、int、double、bool等)的结构的更一般的情况下,可能会发生aligment不是一个数据数组的情况。但它仍将是“半联合的”。我甚至敢打赌这场演出还是一样的。

理论上,这场演出是一样的。但是,如果您更频繁地访问某些成员,由于cpu缓存的局部性,使用多个阵列将具有更高的性能。但是,当您有多个阵列时,大多数操作将更加困难。

理论上,性能是相同的。但是,如果您更频繁地访问某些成员,由于cpu缓存的局部性,使用多个阵列将具有更高的性能。但是,当您有多个阵列时,大多数操作将更加困难。

我不太明白。。。如果有许多数组,每个数组的长度为100,则第一个工作项在前100个double中访问一个double,在前100个double中不访问任何其他内容。相比之下,假设您有一个包含20个double的结构(假设最初有20个数组,每个数组的长度为100),那么第一个工作项只访问前20个double,其他什么都不访问。所以,这是非常不同的,这会影响凝聚吗?是的,它们是不同的。但它的影响方式与在单个长数组中使用相同的内存顺序相同。因此,结构不是这里的问题。只有你如何使用记忆。黑暗的零,你是完全正确的。我只是吸了一口,试了试。我使用了800万个4倍的结构,而每800万个长的4个双数组。该操作是将800万条线程中的每一条线程的第4个第i个双倍相加。在我的7970 GHZedition上