是否值得通过共享内存传递内核参数?

时间:2013-05-25 23:36:30

标签: cuda gpu-programming gpu-shared-memory

假设我们有一个数组int * data,每个线程将访问该数组的一个元素。由于此数组将在所有线程之间共享,因此它将保存在全局内存中。

让我们创建一个测试内核:

 __global__ void test(int *data, int a, int b, int c){ ... }

我确信data数组将在全局内存中,因为我使用cudaMalloc为此数组分配了内存。至于其他变量,我已经看到一些传递整数而不分配内存的例子,立即到内核函数。在我看来,这些变量是a bc

如果我没有弄错,即使我们不直接调用cudaMalloc为每三个整数分配4个字节,CUDA也会自动为我们做,所以最后变量a bc将在全局内存中分配。

现在这些变量只是辅助变量,线程只读取它们而不是其他任何东西。

我的问题是,将这些变量传输到共享内存不是更好吗?

我想如果我们有10个带1024个线程的块,我们需要10*3 = 304个字节的读取,以便将这些数字存储在共享中每个街区的记忆。

没有共享内存,并且如果每个线程必须读取所有这三个变量一次,则全局内存读取的总量将为1024*10*3 = 30720,这是非常低效的。

现在问题出现了,我对CUDA有些新意,我不确定是否可以将变量a bc的内存转移到共享每个块的内存,而不是让每个线程从全局内存中读取这些变量并将它们加载到共享内存中,因此最终全局内存读取的总量将是1024*10*3 = 30720而不是10*3 = 30。 / p>

在以下website上有以下示例:

 __global__ void staticReverse(int *d, int n)
 {
    __shared__ int s[64];
    int t = threadIdx.x;
    int tr = n-t-1;
    s[t] = d[t];
    __syncthreads();
   d[t] = s[tr];
 }

此处每个线程在共享变量s内加载不同的数据。因此,每个线程根据其索引将指定的数据加载到共享内存中。

就我而言,我只想将变量a bc加载到共享内存中。这些变量总是相同的,它们不会改变,因此它们与线程本身没有任何关系,它们是辅助的,并且每个线程都使用它来运行某些算法。

我该如何处理这个问题?是否可以通过仅执行total_amount_of_blocks*3全局内存读取来实现此目的?

1 个答案:

答案 0 :(得分:12)

GPU运行时已经完美地完成了这项任务,而无需您做任何事情(并且您对CUDA中参数传递如何工作的假设不正确)。目前正在发生这种情况:

  • 在计算能力1.0 / 1.1 / 1.2 / 1.3设备中,内核参数由运行时在共享内存中传递。
  • 在计算能力2.x / 3.x / 4.x / 5.x / 6.x设备中,内核参数由运行时传递到保留的常量存储库(具有带广播的专用高速缓存)中。

所以在你假设的内核中

__global__ void test(int *data, int a, int b, int c){ ... }

dataabc都通过 value 传递给共享内存或常量内存中的每个块(取决于GPU架构)自动。做你的建议没有任何好处。