我正在尝试创建一个并行代码来加速处理非常大(几亿行)的数组.为了与此并行化,我将数据切成8个(我的核心数量)碎片,并尝试将每个工人送到1件.然而,看看我的RAM使用情况,似乎每个工件都发送给每个工作人员,有效地将我的RAM使用量乘以8.最小工作示例:
A = 1:16;
for ii = 1:8
data{ii} = A(2*ii-1:2*ii);
end
Run Code Online (Sandbox Code Playgroud)
现在,当我将这些数据发送给使用parfor它的工作人员时,它似乎发送了完整的单元格,而不仅仅是所需的部分:
output = cell(1,8);
parfor ii = 1:8
output{ii} = data{ii};
end
Run Code Online (Sandbox Code Playgroud)
我实际上在parfor循环中使用了一些函数,但这说明了这种情况.MATLAB实际上是将完整的单元格发送data给每个工作人员,如果是这样,如何让它只发送所需的部分?
在Beignet的优化指南中,这是一个针对英特尔GPU的OpenCL开源实现
工作组大小应大于16并且是16的倍数.
Gen上两个可能的SIMD通道是8或16.为了不浪费SIMD通道,我们需要遵循这个规则.
英特尔处理器显卡Gen7.5的计算架构中也提到:
对于基于Gen7.5的产品,每个EU有七个线程,总共28 千字节的通用寄存器文件(GRF).
...
在Gen7.5计算架构中,大多数SPMD编程模型采用这种样式代码生成和EU处理器执行.实际上,每个SPMD内核实例似乎在其自己的SIMD通道内串行且独立地执行.
实际上,每个线程同时执行SIMD-Width数量的内核实例.因此,对于计算 内核 的SIMD-16编译,SIMD-16 x 7线程= 112个内核实例可以在单个EU上同时执行.类似地,对于SIMD-32 x 7个线程= 224个内核实例在单个EU上并发执行.
如果我理解正确,使用SIMD-16 x 7 threads = 112 kernel instances作为示例,为了在一个EU上运行224个线程,工作组大小需要为16.然后OpenCL编译器将16个内核实例折叠到16通道SIMD线程中,并执行此操作在7个工作组中进行7次,并在单个EU上运行它们?
问题1:我是否正确到此为止?
但是OpenCL规范也提供了矢量数据类型.因此,通过传统的SIMD编程(如在NEON和SSE中)充分利用欧盟的SIMD-16计算资源是可行的.
问题2:如果是这种情况,使用vector-16数据类型已经明确使用了SIMD-16资源,因此删除了至少16项每工作组限制.是这样的吗?
问题3:如果以上都是真的,那么两种方法如何相互比较:1) OpenCL编译器将112个线程折叠成7个SIMD-16线程; 2) 7个本机线程编码为明确使用vector-16数据类型和SIMD-16操作?
我正在将一些代码从纯 Python 重写为 JAX。我已经达到了这样的程度:在我的旧代码中,我使用 Python 的多处理模块来并行计算单个节点中所有 CPU 核心上的函数,如下所示:
# start pool process
pool = multiprocessing.Pool(processes=10) # if node has 10 CPU cores, start 10 processes
# use pool.map to evaluate function(input) for each input in parallel
# suppose len(inputs) is very large and 10 inputs are processed in parallel at a time
# store the results in a list called out
out = pool.map(function,inputs)
# close pool processes to free memory
pool.close()
pool.join()
Run Code Online (Sandbox Code Playgroud)
我知道 JAX 有 vmap 和 pmap,但我不明白它们是否可以直接替代我上面使用的 multiprocessing.pool.map。 …
parallel-processing multiprocessing spmd python-multiprocessing jax