I have a newbie doubt regarding how do CUDA kernels work.
If have the following code (which use the function cuPrintf
taken from here):
#include "cuPrintf.cu"
__global__ void testKernel(int param){
cuPrintf("Param value: %d\n", param);
}
int main(void){
// initialize cuPrintf
cudaPrintfInit();
int a = 456;
testKernel<<<4,1>>>(a);
// display the device's greeting
cudaPrintfDisplay();
// clean up after cuPrintf
cudaPrintfEnd();
}
The output of the execution is:
Param value: 456
Param value: 456
Param value: 456
Param value: 456
I cannot get how the kernel can read the correct value o开发者_运维知识库f the parameter I pass, isn't it allocated in the host memory? Can the GPU read from the host memory?
Thanks,
Andrea
According to the section E.2.5.2. Function Parameters in CUDA C Programming Guide
__global__ function parameters are passed to the device:
- via shared memory and are limited to 256 bytes on devices of compute capability 1.x,
- via constant memory and are limited to 4 KB on devices of compute capability 2.x and higher.
The declaration void testKernel(int param)
says that param
is passed by value, not by reference. In other words, the stack contains a copy of a
's value, not a pointer to a
. CUDA copies the stack to the kernel running on the GPU.
According to the CUDA Programming Guide (Appendix B.16) the arguments are passed via shared memory to the device.
The arguments to the execution configuration are evaluated before the actual function arguments and like the function arguments, are currently passed via shared memory to the device.
The parameters are passed to the kernels when you invoke them; otherwise how else would you communicate with the GPU? It is the same as the idea behind setting a uniform in a shader.
In the runtime API, parameters for global functions are implicitly marshalled and copied from the host to the device.
NVCC compiler generates code that hides the marshalling from you. You can find the Parameter sizes and limitations in the CUDA Programming Guide
精彩评论