19

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 of the parameter I pass, isn't it allocated in the host memory? Can the GPU read from the host memory?

Thanks,

Andrea

1
  • Function variables are implicitly marshalled and copied to the device by NVCC compiler. Commented Feb 26, 2018 at 3:37

5 Answers 5

22

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.
Sign up to request clarification or add additional context in comments.

Comments

15

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.

3 Comments

So, if I correctly understood, during the kernel execution param will be into the GPU memory stack. Thus, if I read it many time, I will not access any "host memory", decreasing performance, right?
The documentation isn't really clear on where kernel arguments are stored. You can assume it's in fast memory though: registers, shared, or constant. As kirbuchi said in his answer, the CUDA Programming Guide (section B.13 in the 3.0 Guide) says "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".
Perfect. Thanks again for all your answers.
4

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.

4 Comments

That the quote refers to the execution config arguments (4 and 1) not the function arguments (a == 456) which is what the OP asked about.
@Steve You're right, but it compares them to the function arguments which it says are also passed via shared memory. Should've emphasized that part :)
The method for passing kernel parameters varies with architecture. Compute capability 1.* devices put the values in shared memory. Compute capability >= 2.0 put the values in constant memory.
That's doesn't really make scene , cause you can modify each argument, let's say ar is a int argument, therefore - you my write: at = threadIdx.x; which doesn't make scene cause you modify the solely shared value for all threads in a block.
0

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.