Cuda 使用本地/共享内存作为全局缓存

Cuda 使用本地/共享内存作为全局缓存,cuda,opencl,Cuda,Opencl,我有一个图像处理内核,它使用的标志缓冲区太大,无法放入本地内存。这些标志以可预测的光栅模式(从左上方到右下方)访问 我的想法是将标志存储在全局内存中,并使用本地内存作为全局内存的缓存。因此,当我沿着光栅模式前进时,我想从全局到局部读取标志,进行一些处理,然后将标志写回全局。但是,我想隐藏所涉及的延迟 因此,假设我以一系列位置访问我的图像:a1、a2、a3…… 我想做以下工作: 获取a1标志 获取a2标志 提取a2标志时,处理a1位置并存储回 到全局内存 获取a3标志 提取a3标志时,处理a2位置

我有一个图像处理内核,它使用的标志缓冲区太大,无法放入本地内存。这些标志以可预测的光栅模式(从左上方到右下方)访问

我的想法是将标志存储在全局内存中,并使用本地内存作为全局内存的缓存。因此,当我沿着光栅模式前进时,我想从全局到局部读取标志,进行一些处理,然后将标志写回全局。但是,我想隐藏所涉及的延迟

因此,假设我以一系列位置访问我的图像:
a1、a2、a3……
我想做以下工作:

  • 获取
    a1
    标志
  • 获取
    a2
    标志
  • 提取
    a2
    标志时,处理
    a1
    位置并存储回 到全局内存
  • 获取
    a3
    标志
  • 提取
    a3
    标志时,处理
    a2
    位置并回存 到全局内存
  • 等等
  • 我应该如何构造代码以确保延迟被隐藏? 我是否需要使用
    vload/vstore
    来执行此操作?还是GPU硬件
    延迟是否自动隐藏

    无需手动执行此操作。 GPU设备已经为您做到了这一点

    compute core分批执行一些工作项(warp),当该批由于等待全局内存而无法继续时,它会同时启动另一批并将该批置于睡眠状态。

    CUDA概念可能是一个适合您的案例的好工具。访问模式针对图像处理进行了优化,并使用纹理缓存,因此无需自己执行缓存。纹理缓存是逐块的,因此您可能希望使用2D线程分布将小正方形由单个块处理


    隐藏延迟自然是通过调度硬件无法同时处理的线程和块来完成的。根据设备的类型,“每个多处理器的最大驻留线程数”(自CC 3.0以来的2048个)与每个SM的CUDA内核数之间的比率将为您提供一个很好的提示,以计算您希望调度为最佳隐藏延迟的线程总数(线程*块)。请注意,最佳值实际上取决于代码本身、内核所需的寄存器数量等。

    关键是确保读取合并-这是获得峰值内存带宽的唯一方法。然后,将内核复杂度保持在足够低的水平,以确保占用率足够高,从而确保所有计算都隐藏在内存访问之后。然后你将尽可能快地跑

    看起来您确实具备拥有高效内核的所有要求。 您可以预测数据访问模式,从gmem合并读取数据,并且您确实有一个复杂的处理过程

    因此,在暂停的扭曲加载值时,硬件将通过在“飞行中”的常驻块中拾取扭曲来处理,从而自动隐藏全局加载延迟,但您必须有足够多的可启动扭曲。我想你可能在这里遇到两个挑战:

    • 没有足够的线程/块(占用率可能较低),因此 这意味着,当另一个warp从全局加载值时,硬件将无法拾取准备好处理的warp(这可能是因为您的内核使用了太多的资源来启动,所以处理器可以一次处理几个,或者因为您只启动了几个)
    • 并行处理是不够的,因此,即使您有一个很好的访问模式,但您的内核有大量的“顺序”处理或is执行依赖项,甚至大量的同步,因此warp将暂停,直到值被完全处理,并且由于所有正在运行的warp都已暂停,因此,即使要执行大量处理,您的性能也可能很差
    很难说你有哪一个,但是一些实验可以帮助你。和应该帮助您确定内核限制。你甚至可能撞上一辆汽车

    请注意,“本地”内存是片外内存(作为全局内存),但一些硬件允许它缓存在L1中。看起来您甚至可以使用共享内存来改进您的处理,如


    因此,基本上,只要您拥有80%以上的可供使用的扭曲,您就不会有隐藏Latency的问题。

    您是否尝试过使用?
    屏障需要确保所有工作项在允许它们继续之前都达到内核中的某一点。但是,这不会影响内存事务的延迟。谢谢。我问这个问题的原因是我已经试过了,我的表现很糟糕。所以,我想重组我的代码,以更好地利用延迟隐藏。关键是要确保您的读取是合并的-这是获得峰值内存带宽的唯一方法。然后,将内核复杂度保持在足够低的水平,以确保占用率足够高,从而确保所有计算都隐藏在内存访问之后。那么你会跑得尽可能快。谢谢,@Dithermaster。请输入此作为答案,我将接受。我的读取是合并的,因此内存带宽被尽可能有效地使用。但是,内核的复杂性很高,无法将其分解。