我有一大堆float
名为source_array
,大小约为50.000。我目前正在尝试在阵列上实现一系列修改并对其进行评估。基本上是伪代码:
__kernel void doSomething (__global float *source_array, __global boolean *res. __global int *mod_value) {
// Modify values of source_array with mod_value;
// Evaluate the modified array.
}
所以在这个过程中我需要一个变量来保存修改后的数组,因为source_array
应该是所有工作项的常量,如果我直接修改它可能会干扰另一个工作项(不确定是否我就在这里。)
问题是数组对于私有内存来说太大了,因此我无法在内核代码中初始化。在这种情况下我该怎么做?
我考虑将另一个参数放入方法中,作为修改数组的占位符,但它再次与其他工作项相关。
答案 0 :(得分:2)
GPU上的专用“存储器”字面上由寄存器组成,寄存器通常供不应求。因此,OpenCL中的__private
地址空间不适用于此,因为我相信您已经找到了。
Victor的回答是正确的 - 如果您确实需要每个工作项的临时内存,则需要创建一个(全局)缓冲区对象。如果所有工作项都需要独立地改变它,那么它将需要<WORK-ITEMS> * <BYTES-PER-ITEM>
的大小,并且每个工作项将需要使用它自己的缓冲区片。如果它只是暂时的,您永远不需要将其复制回主机内存。
然而,这听起来像是一种访问模式,它在GPU上工作效率非常低。如果以不同方式分解问题,您会做得更好。例如,您可以使整个工作组在数组的某个子范围内协调工作 - 将子范围复制到本地(组共享)内存中,工作在组中的工作项之间划分,结果是写回全局内存,下一个子范围读取到本地等。组中工作项之间的协调很多比访问大量全局内存的每个工作项更有效我们只能如果您对要尝试执行的计算更具体,请帮助您使用此算法方法。
答案 1 :(得分:1)
为什么不在OpenCL主机内存缓冲区中初始化此数组。即。
const size_t buffer_size = 50000 * sizeof(float);
/* cl_malloc, malloc or new float [50000] or = {0.1f,0.2f,...} */
float *host_array_ptr = (float*)cl_malloc(buffer_size);
/*
put your data into host_array_ptr hear
*/
cl_int err_code;
cl_mem my_array = clCreateBuffer( my_cl_context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, buffer_size, host_array_ptr, &err_code );
然后你可以在OpenCL内核中使用这个cl_mem my_array