11

我正在编写一个图像处理应用程序,我必须以未合并的方式获取像素数据。

最初我使用全局内存实现了我的算法。后来我使用纹理内存重新实现了它。令我惊讶的是,它变得更慢了!我想,cudaMalloc/text1Dfetch 样式可能有问题,所以我将其更改为 cudaArray/tex2D。没有改变。

然后我偶然发现了 Shane Cook 的“CUDA Programming”,他在其中写道:

由于计算 1.x 硬件没有缓存可言,每个 SM 的 6-8K 纹理内存提供了在此类设备上真正缓存数据的唯一方法。然而,随着 Fermi 及其高达 48 K 的 L1 缓存和高达 768 K 的共享 L2 缓存的出现,这使得纹理内存的缓存属性的使用在很大程度上已经过时。Fermi 上仍然存在纹理缓存,以确保与前几代代码的向后兼容性。

我有 GeForce GT 620M(费米,计算上限。2.1)。

所以我需要一些专业人士的建议!我是否应该通过纹理缓存深入挖掘纹理内存以优化性能?或者我应该更好地坚持使用全局内存和 L1/L2 缓存?

4

1 回答 1

12

纹理在计算能力 >= 2.0 的设备上确实很有用。

Textures 和 cudaArrays 可以使用存储在空间填充曲线中的内存,由于更好的 2D 空间局部性,这可以实现更好的缓存命中率。

纹理缓存与其他缓存是分开的。所以它有自己的专用内存和带宽,从它读取不会干扰其他缓存。如果您的 L1/L2 缓存有很大压力,这可能会变得很重要。

纹理还提供内置功能,例如插值、各种寻址模式(clamp、wrap、mirror)和浮点坐标的标准化寻址。这些可以在没有任何额外成本的情况下使用,并且可以大大提高需要此类功能的内核的性能。

在早期的 CUDA 架构中,纹理和 cudaArrays 不能由内核编写。在计算能力 >= 2.0 的架构上,它们可以通过 CUDA 表面编写。

确定是否应该在全局内存中使用纹理或常规缓冲区归结为内存的预​​期使用和访问模式。这将是特定于项目的。

您正在使用 Fermi 架构,设备已更名为 6xx 系列。

对于 Kepler 架构的用户,请查看 NVIDIA 的Inside Kepler演示文稿。特别是幻灯片Texture PerformanceTexture Cache Unlockedconst __restrict Example

于 2013-10-30T17:34:54.023 回答