Optimization CUDA分析-高共享事务/访问,但本地重播率低

Optimization CUDA分析-高共享事务/访问,但本地重播率低,optimization,cuda,shared-memory,pycuda,Optimization,Cuda,Shared Memory,Pycuda,运行VisualProfiler后,GuidedAnalysis告诉我,我的内存被限制了,尤其是我的共享内存访问没有很好地对齐/访问-基本上,我访问共享内存的每一行都被标记为每次访问2个事务 然而,我不明白为什么会这样(我的共享内存被填充/跨步,这样就不应该有银行冲突),所以我回去检查了共享重放指标——也就是说,只有0.004%的共享访问被重放 那么,这里发生了什么,我应该看什么来加速我的内核 编辑:最小复制: import numpy as np import pycuda.autoinit

运行VisualProfiler后,GuidedAnalysis告诉我,我的内存被限制了,尤其是我的共享内存访问没有很好地对齐/访问-基本上,我访问共享内存的每一行都被标记为每次访问2个事务

然而,我不明白为什么会这样(我的共享内存被填充/跨步,这样就不应该有银行冲突),所以我回去检查了共享重放指标——也就是说,只有0.004%的共享访问被重放

那么,这里发生了什么,我应该看什么来加速我的内核

编辑:最小复制:

import numpy as np
import pycuda.autoinit
import pycuda.driver as cuda
from pycuda.compiler import SourceModule
import pycuda.gpuarray as gp

mod = SourceModule("""
(拆分代码块以获得Python和CUDA/C++着色)

(同上)

options=['-std=c++11']
#等同于身份(arr,64);
identity=mod.get_函数(“identity”)
标识(gp.Zero((64,64),np.ubyte,np.int32(64),block=(32,32,1))

每次访问2个事务,共享重播开销0.083。将
dim2
减小到8可以解决这个问题,我也不明白。

部分答案:我对共享内存库的工作原理有一个根本性的误解(即,它们每个都有大约1000个字节的内存库),因此没有意识到它们是循环的,因此,过多的填充意味着32行元素可能会多次使用每个库

不过,据推测,这场冲突并不是每次都会发生——相反,从数字上看,一个街区发生85次


我将在这里停留一天,希望能有一个更完整的解释,然后关闭并接受这个答案。

看到完成的代码是不可能的。请添加一个。给你question@talonmies好吧,我想知道一般情况下会发生什么/这种模式通常会指示什么,但当然,我会在早上看到我可以添加什么。如果您加载的是8字节的量,则每个访问将包含(至少)2个事务(例如,
double
int2
float2
)。这并不意味着共享内存访问没有很好地对齐,也不意味着有任何问题,这是正常的(在这种特殊情况下)。每次访问2笔交易也不意味着(必然)存在银行冲突。
typedef unsigned char ubyte;

__global__ void identity(ubyte *arr, int stride) 
{
    const int dim2 = 16;
    const int dim1 = 64;
    const int dim0 = 33;
    int shrstrd1 = dim2;
    int shrstrd0 = dim1 * dim2;
    __shared__ ubyte shrarr[dim0 * dim1 * dim2];

    auto shrget = [shrstrd0, shrstrd1, &shrarr](int i, int j, int k) -> int{ 
        return shrarr[i * shrstrd0 + j * shrstrd1 + k]; 
    };

    auto shrset = [shrstrd0, shrstrd1, &shrarr](int i, int j, int k, ubyte val) -> void {
        shrarr[i * shrstrd0 + j * shrstrd1 + k] = val;
    };

    int in_x = threadIdx.x;
    int in_y = threadIdx.y;

    shrset(in_y, in_x, 0, arr[in_y * stride + in_x]);
    arr[in_y * stride + in_x] = shrget(in_y, in_x, 0);
}
""",
options=['-std=c++11'])

#Equivalent to identity<<<1, dim3(32, 32, 1)>>>(arr, 64);
identity = mod.get_function("identity")
identity(gp.zeros((64, 64), np.ubyte), np.int32(64), block=(32, 32, 1))