CUDA:curand_统一全局内存对齐
在分析一个项目时,我注意到对CUDA:curand_统一全局内存对齐,c,random,cuda,C,Random,Cuda,在分析一个项目时,我注意到对curand\u uniform的调用在全局内存访问方面存在问题。例如,使用内核创建的随机数生成器,如下所示: __device__ curandState randGPU_d_state[200000]; __global__ void initCurand(const unsigned long seed) { int i = blockIdx.x * blockDimx. + threadIdx.x; if (i < 200000) cu
curand\u uniform
的调用在全局内存访问方面存在问题。例如,使用内核创建的随机数生成器
,如下所示:
__device__ curandState randGPU_d_state[200000];
__global__ void
initCurand(const unsigned long seed)
{
int i = blockIdx.x * blockDimx. + threadIdx.x;
if (i < 200000)
curand_init(seed, i, 0, &randGPU_d_state[i]);
}
当分析'Global Memory Access Pattern'
为'Global Load L2 Transactions/Access=31.8,Ideal Transactions/Access=8[12000个L2事务,总共执行377次]”时,导致NVIDIA Visual Profiler
抛出这一行
事实上,我在同一条线上收到了7条这样的警告
此外,如果我改用curand_normal
,NVIDIA Visual Profiler还会警告curand_normal.h
的第310、312、313、315和316行出现问题,并且理想事务/访问
的比率为4/8
我相信我正在访问合并的状态(虽然我没有在它里面打结内存的细节,但仍然在访问合并的状态变量),因此,为什么这些坏比率是预设的?您关于合并内存访问的假设是不正确的。如果您运行类似这样的操作:
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <curand_kernel.h>
__device__ curandState randGPU_d_state[200000];
__global__ void
initCurand()
{
printf("%ld\n", sizeof(randGPU_d_state[0]));
}
int main()
{
initCurand<<<1,1>>>();
cudaDeviceReset();
return 0;
}
#包括
#包括
#包括
#包括
__设备管理州和GPU d_州[200000];
__全局无效
initCurand()
{
printf(“%ld\n”,sizeof(randGPU_d_state[0]);
}
int main()
{
initCurand();
cudaDeviceReset();
返回0;
}
您将看到它为sizeof(curandState)
打印48。我不知道有什么方法可以完全合并访问这么大的类型数组。你能在其中添加一个更明确的问题吗?我明白了,所以这是不可避免的?在使用curand库时,我无法摆脱这个问题?@James:是的,如果你想在全局内存中存储和访问大量这样的随机生成器状态,这是不可避免的。但你为什么要这么做还不清楚。我看不出有必要这样做的用例,也许我用了错误的方法。我相信两者都使用了类似的方法,尽管它们没有声明randGPU状态[200000]
而是声明为指针,然后声明cudaMalloc((void**)和randGPU状态/Synapses,2000*sizeof(curandState))代码>
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <curand_kernel.h>
__device__ curandState randGPU_d_state[200000];
__global__ void
initCurand()
{
printf("%ld\n", sizeof(randGPU_d_state[0]));
}
int main()
{
initCurand<<<1,1>>>();
cudaDeviceReset();
return 0;
}