OpenCL中工作项和全局内存之间的内存传输?

时间:2014-04-10 15:30:19

标签: opencl

我对工作项和全局内存之间的数据传输方式有一些疑问。让我们考虑以下非常低效的内存绑定内核。

__kernel void reduceURatios(__global myreal *coef, __global myreal *row, myreal ratio)
{
    size_t gid = get_global_id(0);//line no 1

    myreal pCoef = coef[gid];//line no 2
    myreal pRow = row[gid];//line no 3

    pCoef = pCoef - (pRow * ratio);//line no 4
    coef[gid] = pCoef;//line no 5
}
  1. 工作组中的所有工作项都开始执行第1行 同一时间?
  2. 工作组中的所有工作项都开始执行第2行 同一时间?
  3. 假设工作组中的不同工作项完成执行行 在不同的时间没有4。早期完成的那些等待,以便, 所有工作项同时将数据传输到全局内存 在第5行?
  4. 所有工作项同时退出计算单元 早期完成的工作项目必须等到所有工作项目都有 完成执行?
  5. 假设每个内核必须从全局内存中执行2次读取。是吗 更好地一个接一个地执行这些语句或者是它 最好在2次读取之间执行一些计算语句 执行?
  6. 上面显示的内核是GPU的内存绑定。有什么办法吗? 哪些表现可以改善?
  7. 是否有任何避免记忆限制的一般指导原则?

1 个答案:

答案 0 :(得分:1)

在下面找到我的答案:(感谢sharpneli获得AMD GPU和warp的好评)

  1. 通常是。但取决于硬件。你不能直接期望这种行为,并在这个"有序执行"上设计你的算法。这就是barriersmem_fences存在的原因。例如,一些GPU仅按顺序执行WG的WI的子集。在CPU中,它们甚至可能完全无序运行。
  2. 与答案1相同。
  3. 在答案1中,他们很可能不会在不同的时间完成,所以是的。但是你必须记住,这是一个很好的功能,因为对内存的大写操作比许多小写操作更有效。
  4. 通常是(见答案1)
  5. 最好将读取与操作嵌入,但编译器已经考虑到这一点并重新排序操作顺序以隐藏读/写效果的延迟。当然,编译器永远不会移动可以更改结果值的代码。除非您手动禁用编译器优化,否则这是OpenCL编译器的典型行为。
  6. 不,从内核的角度来看,它无法以任何方式得到改进。
  7. 一般规则是,输入的每个存储单元是否被多个WI使用?
    • 否(1个全局 - > 1个私有) (这是问题内核的情况)
    • 然后,该内存是全局的 - >私有的,并且没有办法改进它,不使用本地内存,因为这将是浪费时间。
    • YES(1 global-> X private)
    • 首先尝试移动全局内存本地内存,然后直接从本地读取每个WI的私有内存。根据重用量(可能只有2个WI使用相同的全局数据),如果计算量已经很高,则可能甚至不值得。您必须考虑额外内存使用和全局访问增益之间的权衡。对于图像处理来说,这通常是一个好主意,对于其他类型的过程而言并非如此。
  8. 注意:如果您尝试写入全局内存,则会应用相同的过程。在写入全局之前,许多WI在本地存储器中操作总是更好。但如果每个WI写入全局的唯一地址,则直接写入。