我正在编写一个图像处理应用程序,我必须以非合并的方式获取像素数据.
最初我使用全局内存实现了我的算法.后来我用纹理内存重新实现了它.令我惊讶的是它变慢了!我想,也许cudaMalloc/text1Dfetch样式有问题,所以我把它改成了cudaArray/tex2D.没有改变.
然后我偶然发现了Shane Cook的"CUDA编程",他写道:
由于计算1.x硬件没有缓存可言,每个SM的6-8K纹理内存提供了在这些设备上真正缓存数据的唯一方法.然而,随着Fermi及其高达48 K L1高速缓存和高达768 K共享L2高速缓存的出现,这使得纹理存储器的缓存属性的使用基本上已经过时.Fermi上仍然存在纹理缓存,以确保与前几代代码的向后兼容性.
我有GeForce GT 620M(Fermi,计算上限2.1).
所以我需要专业人士的一些建议!我是否应该深入挖掘纹理内存,其纹理缓存试图优化性能?或者我应该更好地坚持全局内存和L1/L2缓存?
Rog*_*ahl 11
纹理确实可用于计算能力> = 2.0的设备.
纹理和cudaArrays可以使用存储在空间填充曲线中的存储器,由于更好的2D空间局部性,这可以允许更好的缓存命中率.
纹理缓存与其他缓存分开.因此它有自己的专用内存和带宽,从中读取不会干扰其他缓存.如果您的L1/L2缓存存在很大压力,这可能会变得很重要.
纹理还提供内置功能,如插值,各种寻址模式(钳位,包裹,镜像)和带浮点坐标的标准化寻址.这些可以在没有任何额外成本的情况下使用,并且可以极大地提高需要这种功能的内核的性能.
在早期的CUDA架构中,纹理和cudaArrays无法由内核编写.在计算能力的架构> = 2.0时,可以通过CUDA表面编写它们.
确定是否应在全局内存中使用纹理或常规缓冲区归结为内存的预期用法和访问模式.它将是项目特定的.
您正在使用Fermi架构,其设备已重新命名为6xx系列.
对于那些采用Kepler架构的人,请查看NVIDIA的Inside Kepler演示文稿.特别是幻灯片Texture Performance
,Texture Cache Unlocked
和const __restrict Example
.