C++ 不使用内核写入CUDA中的共享内存

C++ 不使用内核写入CUDA中的共享内存,c++,memory,cuda,main,shared,C++,Memory,Cuda,Main,Shared,我想在main()函数中创建一个数组,输入所有正确的值,然后让共享内存中的线程立即使用这个数组 我在CUDA中查找的每个如何使用共享内存的示例都有线程写入共享数组,但我希望我的共享数组在内核启动之前立即可用 任何帮助都将不胜感激。提前谢谢 一些上下文:我想要的共享数组永远不会更改,并且由所有线程读取 编辑:显然这在共享内存中是不可能的。有人知道只读缓存是否可行吗?不可能。填充的唯一方法是在CUDA内核中使用线程 如果您希望一组(只读)数据在启动时可供内核使用,那么当然可以使用。可以使用文档中指定

我想在main()函数中创建一个数组,输入所有正确的值,然后让共享内存中的线程立即使用这个数组

我在CUDA中查找的每个如何使用共享内存的示例都有线程写入共享数组,但我希望我的共享数组在内核启动之前立即可用

任何帮助都将不胜感激。提前谢谢

一些上下文:我想要的共享数组永远不会更改,并且由所有线程读取


编辑:显然这在共享内存中是不可能的。有人知道只读缓存是否可行吗?

不可能。填充的唯一方法是在CUDA内核中使用线程

如果您希望一组(只读)数据在启动时可供内核使用,那么当然可以使用。可以使用文档中指定的API(即
cudaMemcpyToSymbol
)在主机代码上/由主机代码设置此类内存

\uuuu常量\uuuu
只有当每个线程在给定的访问周期内访问同一位置时,内存才真正有用,例如

int myval = constant_data[12];

否则,使用普通全局内存(静态或动态分配),使用适当的主机API进行初始化(动态:
cudaMemcpy
,静态:
cudaMemcpyToSymbol
)。

这是不可能的。填充的唯一方法是在CUDA内核中使用线程

如果您希望一组(只读)数据在启动时可供内核使用,那么当然可以使用。可以使用文档中指定的API(即
cudaMemcpyToSymbol
)在主机代码上/由主机代码设置此类内存

\uuuu常量\uuuu
只有当每个线程在给定的访问周期内访问同一位置时,内存才真正有用,例如

int myval = constant_data[12];

否则,使用普通全局内存(静态或动态分配),使用适当的主机API进行初始化(动态:
cudaMemcpy
,静态:
cudaMemcpyToSymbol

首先,让所有线程将表复制到shmem中

同步线程

访问内核中的数据

如果您对数据进行了相当随机的访问,并且希望平均多次触摸每个条目,那么这将是一个巨大的性能提升。实际上,您将shmem用作托管缓存,并将负载从DRAM聚合到shmem中一次以供多次使用。此外,shmem对未平衡荷载没有处罚

例如,您可以编写如下代码:

const int buffer_size = 8192; // assume an 8k buffer
float *device_buffer = ; // assume you have a buffer already on the device with the data you want.

my_kernel<<<num_blocks, num_threads, buffer_size>>>(..., buffer_size, device_buffer);

__global__ void my_kernel(..., int buffer_size, const float *device_buffer) {
   extern __shared__ float shmem_buffer[];
   for (int idx = threadIdx.x; idx < buffer_sze; idx += blockDim.x) {
       shmem_buffer[idx] = device_buffer[idx];
   }
   __syncthreads();

   // rest of your kernel goes here.  You can access data in shmem_buffer;
}
const int buffer\u size=8192;//假设有8k缓冲区
浮点*设备缓冲区=;//假设设备上已经有一个缓冲区,其中包含所需的数据。
我的内核(…,缓冲区大小,设备缓冲区);
__全局\uuuuu无效我的\u内核(…,int buffer\u size,const float*device\u buffer){
外部共享浮点内存缓冲区[];
对于(int idx=threadIdx.x;idx

换句话说,您只需要显式地对副本进行编码。由于DRAM的所有负载都将完美结合,因此这应该接近最佳效率。

虽然您请求的特定行为无法自动实现,但这实际上是一种相当常见的CUDA范例:

首先,让所有线程将表复制到shmem中

同步线程

访问内核中的数据

如果您对数据进行了相当随机的访问,并且希望平均多次触摸每个条目,那么这将是一个巨大的性能提升。实际上,您将shmem用作托管缓存,并将负载从DRAM聚合到shmem中一次以供多次使用。此外,shmem对未平衡荷载没有处罚

例如,您可以编写如下代码:

const int buffer_size = 8192; // assume an 8k buffer
float *device_buffer = ; // assume you have a buffer already on the device with the data you want.

my_kernel<<<num_blocks, num_threads, buffer_size>>>(..., buffer_size, device_buffer);

__global__ void my_kernel(..., int buffer_size, const float *device_buffer) {
   extern __shared__ float shmem_buffer[];
   for (int idx = threadIdx.x; idx < buffer_sze; idx += blockDim.x) {
       shmem_buffer[idx] = device_buffer[idx];
   }
   __syncthreads();

   // rest of your kernel goes here.  You can access data in shmem_buffer;
}
const int buffer\u size=8192;//假设有8k缓冲区
浮点*设备缓冲区=;//假设设备上已经有一个缓冲区,其中包含所需的数据。
我的内核(…,缓冲区大小,设备缓冲区);
__全局\uuuuu无效我的\u内核(…,int buffer\u size,const float*device\u buffer){
外部共享浮点内存缓冲区[];
对于(int idx=threadIdx.x;idx

换句话说,您只需要显式地对副本进行编码。由于来自DRAM的所有负载都将完美地结合在一起,这应该接近最佳效率。

真糟糕。您知道在compute 3.5设备中使用只读缓存是否可以实现我想要的功能吗?谢谢。让我们澄清一下,SO不是聊天服务。如果你有一个新问题,把它作为一个新问题发布。如果60%的线程读取相同的地址,而其他40%的线程以相同的比例读取其他3个地址,你认为恒定内存比全局内存更有效吗?很难说。在每种情况下,确切的访问模式都会影响性能。您可以尝试编写一个基准来比较这两种情况;这应该不难,真糟糕。您知道在compute 3.5设备中使用只读缓存是否可以实现我想要的功能吗?谢谢。让我们澄清一下,SO不是聊天服务。如果你有一个新问题,把它作为一个新问题发布。如果60%的线程读取相同的地址,而其他40%的线程以相同的比例读取其他3个地址,你认为恒定内存比全局内存更有效吗?很难说。在每种情况下,确切的访问模式都会影响性能。您可以尝试编写一个基准来比较