Cuda 3D纹理内存是如何缓存的?

Cuda 3D纹理内存是如何缓存的?,cuda,Cuda,我有一个应用程序,其中96%的时间用于3D纹理内存插值读取(图中的红点) 我的内核设计为在一条任意穿过纹理内存的线上执行1000次内存读取,每行一个线程(蓝线)。这些线路密集,彼此非常靠近,几乎平行 这张图片展示了我所说的概念。假设图像是3D纹理存储器中的一个“切片”,例如z=24。该图像对所有z重复显示。 目前,我只是一行接一行地执行线程,但我意识到,如果调用同一块中的相邻行,我可能会受益于纹理内存局部性,从而减少内存读取的时间 我的问题是 如果我有带线性插值的3D纹理,我怎样才能从数据局

我有一个应用程序,其中96%的时间用于3D纹理内存插值读取(图中的红点)

我的内核设计为在一条任意穿过纹理内存的线上执行1000次内存读取,每行一个线程(蓝线)。这些线路密集,彼此非常靠近,几乎平行

这张图片展示了我所说的概念。假设图像是3D纹理存储器中的一个“切片”,例如
z=24
。该图像对所有
z
重复显示。

目前,我只是一行接一行地执行线程,但我意识到,如果调用同一块中的相邻行,我可能会受益于纹理内存局部性,从而减少内存读取的时间

我的问题是

  • 如果我有带线性插值的3D纹理,我怎样才能从数据局部性中获益最大?通过在2D中运行同一块中的相邻线或在3D中运行相邻线(3D相邻线或每个切片仅相邻线)

  • 缓存有多大(或者如何在规格中检查)?它是否在每个方向上加载所请求的体素和+-50?这将直接关系到我在每个块中放置的相邻行的数量

  • 插值如何应用于纹理内存缓存?插值是否也在缓存中执行,或者插值将减少内存延迟,因为它需要在文本内存本身中执行



如果对NVIDIA TESLA K40、CUDA 7.5有帮助的话,我将在研究构建TIGRE工具箱的基础上给出一个基准答案。

由于这个问题已经过时,而且我提出的一些问题似乎没有答案。您可以在中获取源代码

由于答案是基于工具箱的特定应用程序,计算机断层扫描,这意味着我的结果不一定适用于所有使用纹理内存的应用程序。此外,我的GPU(见上文)相当不错,因此不同硬件的里程可能会有所不同


细节 需要注意的是:这是一个锥束计算机断层扫描应用程序。这意味着:

  • 这些线条大致沿图像均匀分布,覆盖了大部分区域
  • 这些线或多或少与相邻线平行,且主要始终位于一个平面内。它们总是或多或少水平,从不垂直
  • 线顶部的采样率是相同的,这意味着相邻线将始终对彼此非常接近的下一个点进行采样
所有这些信息对于内存位置都很重要

此外,如问题中所述,内核96%的时间是内存读取,因此可以安全地假设所报告的内核时间的变化是由于内存读取速度的变化造成的


问题 如果我有带线性插值的3D纹理,我怎样才能从数据局部性中获益最大?通过在2D中运行同一块中的相邻线或在3D中运行相邻线(3D相邻线或每个切片仅相邻线)

一旦你对纹理记忆有了更多的经验,你就会发现简单的答案是:尽可能多的相邻线一起运行。图像索引中的内存读取越接近,效果越好

这对于层析成像有效地意味着运行方形探测器像素块。将光线(原始图像中的蓝线)打包在一起

缓存有多大(或者如何在规格中检查)?它是否在每个方向上加载所请求的体素和+-50?这将直接关系到我在每个块中放置的相邻行的数量

虽然说不上来,但根据经验,我发现运行较小的块更好。我的结果显示,对于512^3的图像,使用512^2条光线,采样率为~2个采样/体素,块大小:

32x32 -> [18~25] ms
16x16 -> [14~18] ms
8x8   -> [11~14] ms
4x4   -> [25~29] ms
块大小实际上是一起计算的正方形相邻光线的大小。例如,32x32表示将并行计算1024条X射线,在一个正方形32x32块中彼此相邻。由于在每行中执行完全相同的操作,这意味着在图像上约32x32平面上采集样本,覆盖约32x32x1索引

可以预见,在某些时候,当减少块的大小时,速度会再次变慢,但这至少是(至少对我来说)令人惊讶的低值。我认为这暗示内存缓存从图像中加载相对较小的数据块

此结果显示了原始问题中未询问的附加信息:关于速度的越界样本会发生什么情况。由于向内核添加任何
if
条件都会显著降低内核的速度,因此我对内核编程的方法是在确保超出图像的行中的某个点开始采样,并在类似情况下停止采样。这是通过在图像周围创建一个虚构的“球体”来实现的,并且始终采样相同的量,与图像和线条之间的角度无关

如果您看到我显示的每个内核的时间,您会注意到它们都是
[t~sqrt(2)*t]
,并且我已经检查过,当线条和图像之间的角度是45度的倍数时,时间越长,图像(纹理)中的样本越多

这意味着从图像索引(
tex3d(tex,-5,-5,-5)
)中采样在计算上是免费的。没有时间花在阅读上。读取大量越界点比检查点是否落在图像内部要好,因为
if
条件会减慢内核速度,并且越界采样的成本为零

插值如何应用于纹理
Linear  ->  [11~14] ms
Nearest ->  [ 9~10] ms