繁体   English   中英

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

[英]Is it worthwhile to pass kernel parameters via shared memory?

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

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

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

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

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

现在这些变量只是辅助的,线程只读取它们而没有别的。

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

我想如果我们有101024线程的块,我们需要10*3 = 304字节的读取,以便将数字存储在每个块的共享内存中。

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

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

在以下网站上有这个例子:

 __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全局内存读取来实现此total_amount_of_blocks*3

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都通过自动传递给共享内存或常量内存(取决于GPU架构)中的每个块。 做你的建议是没有优势的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM