我正在努力使用OpenCL specification,因为我发现它有时含糊不清,有人可以尝试回答以下问题吗?
请考虑以下代码:
__kernel void myKernel(...)
{
// Buffer 1
__local float *buffer1[64];
// Buffer 2
__local float *buffer2;
// Buffer 3
__private float *buffer3[64];
// Buffer 4
float *buffer4[64];
int var1 = 1, var2 = 2;
nonKernelFunction(&var1, &var2);
// ...
}
void nonKernelFunction(int *pvar1, int *pvar2)
{
int *pvar;
if (someRunTimeCondition)
pvar = pvar1;
else
pvar = pvar2;
*pvar += 1;
}
1)buffer1和buffer2之间是否存在差异(静态或动态)?
2)buffer3和buffer4的声明是否等效(它们是变量,但我不确定指针)?
3)在GPU上(我认为私有内存只是寄存器),编译器将在哪里分配资源?如果它在全局内存中,是否可以从主机知道运行时将使用多少内存?
4)假设缓冲区3和缓冲区4存储在寄存器中,如何允许缓冲区3 [i] = buffer4 [i](运行时我知道的话)这样的指令?
5)如果缓冲区3和缓冲区4没有存储到寄存器中,那么,如何允许nonKernelFunction代码(var1和var2绝对不在内存中)?
由于
答案 0 :(得分:1)
AFAIK:
1)内核代码中的静态规范与主机通过缓冲区的“动态”规范之间没有技术差异;
2)默认变量是__private所以这不应该有任何区别;
3)私有内存可以在寄存器中分配,如果很小,则使用全局内存; 您可以使用clGetKernelWorkGroupInfo;
查询内核的最低内存要求4)为什么不允许这样做,因为它可能会导致越界错误?
5)var1和var2在GPU的地址空间中,即使不在私有内存中也是如此;访问可能会慢一些。
EDIT1: var1和var2在寄存器中的事实,比如reg1和reg2,应该不是问题,因为代码可能导致伪装配,如:
myKernel:
...
push reg1
push reg2
call nonKernelFunction
...
nonKernelFunction:
test someRunTimeCondition
jz ko
mov [SP+2] reg1
jmp end:
ko:
mov [SP+1] reg1
end:
mov [reg1] reg2
inc reg2
mov reg2 [reg1]
我不知道GPU组件/核心架构是否有很大不同,但在标准CPU上没有问题,因为您使用堆栈来抽象有效位置。
请注意,此处有一个更新版本的规范:) http://www.khronos.org/registry/cl/specs/opencl-1.2.pdf