我正在开发一个内核,每个线程都有很多全局内存访问权限,因此我将它们复制到本地内存中,速度提高了40%。
我想要更快的速度,所以从本地复制到私有,这降低了性能
所以我认为我们不能使用可能会降低性能的私人内存,这是正确的吗?
答案 0 :(得分:14)
Ashwin的答案是正确的方向,但有点误导。
OpenCL将变量的地址空间从物理存储中抽象出来,两者之间不一定有1:1的映射。
考虑在__private地址空间中声明的OpenCL变量,默认情况下包括函数内的自动非指针变量。 NVidia GPU实现将尽可能在寄存器中进行物理分配,只有在寄存器容量不足时才会溢出到物理片外存储器。这种特殊的片外存储器称为“CUDA本地”存储器,并且具有与为__global变量分配的存储器类似的性能特性,这解释了由寄存器溢出引起的性能损失。在这个实现中没有“私有内存”这样的物理内容,只有“私有地址空间”,可以在片上或片外分配。
性能影响不是使用私有地址空间(或“私有内存”)的直接后果,私有地址空间通常分配在高性能内存中。这是因为,在这个实现中,变量太大而无法分配给高性能寄存器,因此被“溢出”到片外存储器。
答案 1 :(得分:1)
(我知道这是一个老问题,但给出的答案并不准确,我在Google搜索过程中看到其他地方存在相互矛盾的答案。)
根据"使用OpenCL进行异构计算" (修订版OpenCL 1.2版):
私有内存是对单个工作项唯一的内存。局部变量 默认情况下,非指针内核参数是私有的。在实践中,这些变量 通常映射到寄存器,虽然私有数组和任何溢出 寄存器通常映射到片外(即长延迟)存储器。
因此,如果您使用大量私有内存,或者在私有内存中使用数组,是的,它可能比本地内存慢。
答案 2 :(得分:0)
在(类似GPU)OpenCL设备中,本地内存在片内并靠近处理元件(PE)。它可能与访问L1缓存一样快。每个线程的私有内存实际上是从片外全局内存中分配的。这远离PE,可能有数百个时钟周期的延迟,从而降低了读写性能。
答案 3 :(得分:0)
James Beilby的回答是正确的方向,但有点偏离道路:
取决于实现,它可能更快或更慢,因为opencl不会强制提供商使用片上或片外存储器,但AMD在价格/性能方面非常擅长OpenCL,所以我会给出一些关于它
AMD实施中的私有内存最快(最小延迟,最高带宽,如主流GPU的22 TB / s)。
附录-d:
您可以看到注册文件, LDS ,常量缓存和全局,这些用于不同的名称空间什么时候有足够的空间给自己。例如,寄存器文件具有22 TB / s,每个计算单元仅约300kB。与用于__本地存储空间的LDS相比,这具有更少的延迟和更多的带宽。总LDS大小甚至小于(每计算单位)。
如果从本地到私有并不好,您应该将本地线程组大小从256减少到64。因此每个线程可以使用更多私有寄存器。
因此,对于此示例AMD gpu,本地内存比全局内存快15倍,私有内存比本地内存快5倍。如果它不适合私有内存,它会溢出到全局内存,所以只有L1-L2缓存才能在这里提供帮助。如果数据没有被重复使用,那么这里没有使用私有寄存器的意义。如果只使用一次,只需从全局流到全局。
对于某些智能手机或cpu,使用私有寄存器可能非常糟糕,因为它们可以映射到其他东西。