【发布时间】:2017-05-23 16:23:47
【问题描述】:
我想生成一个矩阵,它在生成后将被许多线程读取,所以我在程序范围内声明了它。它必须是恒定的,所以我只分配一次值
1) 为什么 openCl 只在声明时要求初始化?
2) 我该如何解决这个问题?
【问题讨论】:
我想生成一个矩阵,它在生成后将被许多线程读取,所以我在程序范围内声明了它。它必须是恒定的,所以我只分配一次值
1) 为什么 openCl 只在声明时要求初始化?
2) 我该如何解决这个问题?
【问题讨论】:
1) 因为你无法告诉 gpu 哪些元素是由哪些线程写入的。常量是由预处理器使用标量引擎准备的,而不是并行引擎。并行引擎需要 N x N 次同步才能实现,其中 N 是参与构建常量缓冲区的线程数。
2-a) 如果要使用常量内存,请在内核中准备一个简单的(__global,非常量)缓冲区,将其用作下一个内核中的常量缓冲区(引擎将其放在常量内存空间中)。但是常数空间很小,所以矩阵应该很小。这需要 2 个内核,意味着内核开销。
2-b) 如果缓存性能足够,只需使用缓冲区。所以它可以在单个内核中(第一个线程组准备矩阵,其余线程使用它计算,直到第一组使用原子函数发出信号才开始)
2-c) 如果本地内存大于常量内存,您可以使用本地内存并自己为每个计算单元构建该矩阵,因此它应该花费相同数量的周期(如果您使用所有内核,可能会更少)和可能比恒定内存快。这不需要线程组之间的通信,所以会很快。
2-d)如果矩阵很大并且您需要大部分带宽,请将其分配到所有内存空间。示例:将矩阵的 1/4 放入常量内存(5 倍带宽),将矩阵的 1/4 放入本地内存(10 倍带宽),将矩阵的 1/4 放入全局内存(缓存性能的 2 倍),将剩余数据放入指令空间(指令本身),因此多个线程将同时在 4 个不同的地方工作,使用所有带宽(常量 + 本地 + 缓存 + 指令缓存)。
【讨论】: