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