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