【发布时间】:2019-06-05 21:01:28
【问题描述】:
我是 OpenCL 的新手,遇到以下问题:
我有一个大数组(6 * 1,000,000 个浮点数)。对于数组的每个元素,我需要进行计算。基本算法在多达 16 个 GPU (Tesla K80) 上运行良好:
1.) 我为每个 GPU 设备的结果创建数组的缓冲区对象和缓冲区对象,并将其写入每个 GPU 内存。
2.) 然后,为每个数组元素生成一个线程,并在 GPU 上的内核中执行计算。
3.) 将结果写入到全局线程id对应的result数组元素中。
4.) 主机读取结果缓冲区。
我现在必须扩展这个算法。一些数组元素(10-100)实际上需要额外的计算来产生额外的结果(另外 12 个浮点数)。
这是一些伪代码。
__kernel void calculation(__global float4 *input_array,
__global float4 *result_array){
int id = get_global_id(0);
//do calculation
float4 result = some_func(input_array[id]);
result_array[id] = result;
if(some_rare_condition){
//do another, much longer calculation
float4 result2 = another_func(input_array[id]);
}
}
问题是我只有一些额外的结果,我不知道存储它们并让主机读取它们的最佳方法是什么。
在我计算出第一个结果之前,我不知道哪些数组元素需要额外计算。
如果这是 C++,我只需为附加结果创建一个向量,为索引创建一个向量。但是,据我所知,OpenCL 内核中没有动态内存容器。
如果我创建一个包含 1,000,000 个元素的第二个结果数组,并且只写入所需的少数几个位置,那么当我将它传递回主机时就会产生瓶颈。
如果我创建一个肯定大于所需的较小数组(例如 1000 个元素),我不确定如何让线程安全地写入它。
【问题讨论】: