c++ Cuda:将主机数据复制到共享内存阵列

xmq68pz9  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(172)

我在主机和设备上定义了一个结构体。在宿主中,我用值初始化这个结构的数组。

MyStruct *h_s = (MyStruct *) malloc(objsize*sizeof(MyStruct));
hs[0] = ...

Mystruct *d_s;
cudaMalloc( &d_s, objsize * sizeof(MyStruct));
cudaMemcpy( d_s, h_s, objsize * sizeof(MyStruct), cudaMemcpyHostToDevice );
init<<< gridSize, blockSize >>> ( d_s );

在我的内核中,我有大约7个函数应该使用这个数组。其中一些是全局的,一些是简单的设备功能。为了简单和高效,我想使用共享内存阵列。

__shared__ Mystruct *d_s;

__global__ void init(Mystruct *theStructArray){
   //How to allocate memory for d_s
   //How copy theStructArray to d_s
}

所以问题是:如何为共享数组分配内存并使用function参数设置其值?

**编辑:**我正在尝试将smallpt代码写入CUDA。

struct Sphere {
    double rad;       // radius
    Vec p, e, c;      // position, emission, color
    Refl_t refl;      // reflection type (DIFFuse, SPECular, REFRactive)

    Sphere(){
        rad = 16.5;
        p = (Vec(27,16.5,47) + Vec(73,16.5,78))*0.5;
        e = Vec();
        c = Vec(0.75, 0.75, 0.75);
        refl = DIFF;
    }

    Sphere(double rad_, Vec p_, Vec e_, Vec c_, Refl_t refl_):
        rad(rad_), p(p_), e(e_), c(c_), refl(refl_) {}

    __device__ double intersect(const Ray &r) const { // returns distance, 0 if nohit
        Vec op = p-r.o; // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0
        double t, eps=1e-4, b=op.dot(r.d), det=b*b-op.dot(op)+rad*rad;
        if (det<0) return 0; else det=sqrt(det);
        return (t=b-det)>eps ? t : ((t=b+det)>eps ? t : 0);
    } 
};
efzxgjgh

efzxgjgh1#

如果您了解共享内存的范围和大小限制,那么问题似乎是
1.如何为共享内存阵列动态保留内存
1.如何在内核中使用动态共享内存
你的内核会变成这样:

__shared__ Mystruct *d_s;

__global__ void init(Mystruct *theStructArray){

    int tid = blockDim.x * blockIdx.x + threadIdx.x;

    // load to shared memory array
    // assumes Mystruct has correct copy assignment semantics
    d_s[threadIdx.x] = theStructArray[tid]

    __syncthreads();

    // Each thread has now loaded one value to the block
    // scoped shared array
}

[免责声明:在浏览器中编写的代码,从未编译或测试过,请注意注解中关于复制分配的警告]
调用主机代码需要向内核调用添加一个额外的参数,以便为共享数组保留内存:

MyStruct *h_s = (MyStruct *) malloc(objsize*sizeof(MyStruct));
hs[0] = ...

Mystruct *d_s;
cudaMalloc( &d_s, objsize * sizeof(MyStruct));
cudaMemcpy( d_s, h_s, objsize * sizeof(MyStruct), cudaMemcpyHostToDevice );
init<<< gridSize, blockSize, blockSize * sizeof(MyStruct) >>> ( d_s );

注意内核调用的<<< >>>节的第三个参数。它指定每个块保留的内存字节数。硬件对您可以分配的共享内存的大小有限制,并且它们可能对硬件限制之外的性能产生额外的影响。
共享内存是CUDA的一个非常有据可查的特性,我推荐Mark Harris's blog和这个Stack Overflow Question作为CUDA中共享内存机制的良好起点。

相关问题