CUDA究竟如何处理内存访问?

时间:2017-01-15 15:35:22

标签: cuda gpgpu

我想知道CUDA硬件/运行时系统如何处理以下情况。

如果warp(以下warp1)指令涉及访问全局内存(加载/存储);运行时系统调度下一个准备好的warp以便执行。

执行新warp时,

  1. "内存访问" warp1是否可以并行进行,即在新的warp运行时?

  2. 运行时系统是否会将warp1放入内存访问等待队列;一旦内存请求完成,warp就会被移入runnable queue?

  3. 与warp1执行相关的指令指针是否会自动递增并与新的warp执行并行,以注释内存请求是否已完成?

  4. 例如,考虑这个伪代码output=input+array[i];,其中outputinput都是映射到寄存器的标量变量,而array则保存在全局内存中。

    要运行上述指令,我们需要在更新输出之前将array[i]的值加载到(临时)寄存器中;即上述指令可以转换为2个宏汇编指令load reg reg=&array[i]output_register=input_register+reg

    我想知道硬件和运行时系统如何处理上述2个宏汇编指令的执行,因为负载不能立即返回

1 个答案:

答案 0 :(得分:3)

我不确定我是否正确理解了您的问题,因此我会在阅读时尽力回答:

  1. 是的,当记忆交易正在进行中时,将继续发布更多独立指令。虽然没有必要切换到不同的扭曲 - 而来自其他扭曲的指令将始终是独立的,来自相同扭曲的以下指令也可以是独立的,并且相同的扭曲可以继续运行(即,进一步的指令可能是从同一个经线发出)。

  2. 没有。正如在1中所解释的,warp可以并且将继续执行指令,直到依赖指令需要加载的结果,或者内存fence / barrier指令要求它等待存储对其他线程可见的效果。登记/> 这可以进一步发布(独立的)加载或存储指令,以便多个存储器事务可以同时在同一个warp中进行。因此,发布加载/存储后的扭曲状态不会从根本上改变,并且在必要时不会停止。

  3. 指令指针将始终自动递增(没有您手动执行此操作的情况,也没有允许这样做的说明)。但是,正如2.暗示的那样,这并不一定表明已经执行了内存访问 - 有单独的硬件来跟踪内存访问的进度。

  4. 请注意,Nvidia完全没有记录硬件实现。如果您搜索Nvidia的专利申请,您可能会发现可能实施的一些迹象。

    直到Fermi生成的GPU(计算能力2.x)完全在硬件中跟踪未完成的内存事务。虽然没有Nvidia记录,但跟踪(记忆)飞行中的交易的常用机制是scoreboarding

    以Kepler开头的新一代GPU(计算能力3.x)以嵌入在着色器汇编代码中的控制字的形式使用一些帮助。虽然没有记载,斯科特格雷已经为他的Maxas麦克斯韦汇编程序改编了这些。他发现(除其他外)控制字包含用于跟踪记忆交易的屏障指令,并且非常友好地在他的Control-Codes维基页面上记录他的发现。