|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- //************************** *********************
- // 2024-3-17-
- // ************************** *********************
- #include <stdio.h>
- #include <stdlib.h>
- #include <cuda_runtime.h>
- #include <device_launch_parameters.h>
- #include <string.h>
- //#include <device_functions.h>
- //使用全局内存来操作
- __global__ void global_reduce_kernel(float* d_out, float* d_in)
- {
- int myId = threadIdx.x + blockIdx.x * blockDim.x; //有多个block.在所有线程的位置
- int tid = threadIdx.x; //在当前block里面的位置
- //在global memory里面做
- //循环的条件是 s 大于 0,每次循环迭代结束后,s 的值右移一位(相当于将其除以 2),以便在下一次迭代中处理更小的数据块
- for (unsigned int s = blockDim.x / 2; s > 0; s >>= 1)
- {
- if (tid < s)
- {
- d_in[myId] += d_in[myId + s];
- }
- __syncthreads(); //每个线程块每次循环结束之后才进行下一次运行
- }
- //最后要的是线程块的所有计算的求和结果
- if (tid == 0)
- {
- d_out[blockIdx.x] = d_in[myId];
- }
- }
- //使用共享内存实现归约
- __global__ void share_reduce_kernel(float* d_out, float* d_in)
- {
- extern __shared__ float sdata[]; //给每一个block定义他们各自的内存;
- int myId = threadIdx.x + blockIdx.x * blockDim.x; //有多个block.在所有线程的位置
- int tid = threadIdx.x; //在当前block里面的位置
- //然后将全局内存的数据复制给共享内存, 之后就不需要再从全局内存读数据,
- //共享数据读取的速度快于全局内存
- sdata[tid] = d_in[myId];
- __syncthreads();
- for (unsigned int s = blockDim.x / 2; s > 0; s >>= 1)
- {
- if (tid < s)
- {
- d_in[myId] += d_in[myId + s];
- }
- __syncthreads(); //每个线程块每次循环结束之后才进行下一次运行
- }
- //最后要的是线程块的所有计算的求和结果
- if (tid == 0)
- {
- d_out[blockIdx.x] = d_in[myId];
- }
- }
- void reduce(float* d_out, float* d_intermediate, float* d_in, int size, bool usesShareMemory)
- {
- const int maxThreadsPerBlock = 1024;
- int threads = maxThreadsPerBlock;
- int blocks = size / maxThreadsPerBlock;
- //这个地方对每个
- if (usesShareMemory)
- {
- share_reduce_kernel <<< blocks, threads, threads* sizeof(float) >>> (float* d_intermediate, float* d_in);
- }
- else
- {
- global_reduce_kernel << < blocks, threads >> > (float* d_intermediate, float* d_in);
- }
- threads = blocks;
- blocks = 1;
- if (usesShareMemory)
- {
- if (usesShareMemory)
- {
- share_reduce_kernel << < blocks, threads, threads * sizeof(float) >> > (float* d_intermediate, float* d_in);
- }
- else
- {
- global_reduce_kernel << < blocks, threads >> > (float* d_intermediate, float* d_in);
- }
- }
- }
- int main(int argc, char** argv)
- {
- int deviceCount;
- cudaGetDeviceCount(&deviceCount);
- if (deviceCount == 0)
- {
- fprintf(stderr, "error: no device surporting\n");
- exit(EXIT_FAILURE);
- }
- int dev = 0;
- cudaSetDevice(dev);
- cudaDeviceProp devProps;
- if (cudaGetDeviceProperties(&devProps, dev) == 0)
- {
- printf("using device %d:\n,", dev);
- printf("%s: global memory: %dB; compute v%d.%d; clock: %d kHZ\n",
- devProps.name, (int)devProps.totalGlobalMem, (int)devProps.major, (int)devProps.major, (int)devProps.clockRate);
- }
- const int ARRAY_SIZE = 1 << 20;
- const int ARRAY_BITE = ARRAY_SIZE * sizeof(float);
- //在cpu上创建存储输入数据的数组
- float h_in[ARRAY_SIZE];
- float sum = 0.0f;
- for (int i = 0; i < ARRAY_SIZE; i++)
- {
- h_in[i] = -1.0f + (float)random() / ((float)RAND_MAX / 2.0f);
- sum += h_in[i];
- }
- //declare GPU memory pointers
- float* d_in, *d_out, * d_intermediate;
- //在GPU上创建存储待处理数据和处理结果的数组
- cudaMalloc((void**)&d_in, ARRAY_BITE);
- cudaMalloc((void**)&d_intermediate, ARRAY_BITE);
- cudaMalloc((void**)&d_out, sizeof(float));
- //将CPU输入数据输入到GPU
- cudaMemcpy(d_in, h_in, ARRAY_BITE, cudaMemcpyHostToDevice);
- int whichKernel = 0;
- if (argc == 2)
- {
- whichKernel = atoi(argv[1]);
- }
- }
复制代码
在你的代码中,出现了几个语法错误导致编译错误。我将逐个指出并给出修正后的代码。
首先,在`global_reduce_kernel`函数中,你想对全局内存的变量进行累加操作,但是你写成了`d_in += d_in`,这是错误的。应该使用`*d_in += *d_in`来对变量进行累加。此外,在最后的求和结果处,你写成了`d_out = d_in`,实际上应该是`*d_out = *d_in`。修正后的代码如下:
- __global__ void global_reduce_kernel(float* d_out, float* d_in)
- {
- int myId = threadIdx.x + blockIdx.x * blockDim.x;
- int tid = threadIdx.x;
- for (unsigned int s = blockDim.x / 2; s > 0; s >>= 1)
- {
- if (tid < s)
- {
- *d_in += *d_in;
- }
- __syncthreads();
- }
- if (tid == 0)
- {
- *d_out = *d_in;
- }
- }
复制代码
接下来,在`share_reduce_kernel`函数中,你定义了一个共享内存`sdata`,但是你忘记给它分配实际的内存空间。共享内存的大小应该是每个线程块的大小(即`blockDim.x * sizeof(float)`)。修正后的代码如下:
- __global__ void share_reduce_kernel(float* d_out, float* d_in)
- {
- extern __shared__ float sdata[];
- int myId = threadIdx.x + blockIdx.x * blockDim.x;
- int tid = threadIdx.x;
- sdata[tid] = d_in[myId];
- __syncthreads();
- for (unsigned int s = blockDim.x / 2; s > 0; s >>= 1)
- {
- if (tid < s)
- {
- sdata[tid] += sdata[tid + s];
- }
- __syncthreads();
- }
- if (tid == 0)
- {
- *d_out = sdata[0];
- }
- }
复制代码
在`reduce`函数中,你调用核函数的方式不正确。应该使用`<<<...>>>`语法来调用核函数,并且传递的参数应该是设备端的指针。修正后的代码如下:
- void reduce(float* d_out, float* d_intermediate, float* d_in, int size, bool usesShareMemory)
- {
- const int maxThreadsPerBlock = 1024;
- int threads = maxThreadsPerBlock;
- int blocks = size / maxThreadsPerBlock;
- if (usesShareMemory)
- {
- share_reduce_kernel<<<blocks, threads, threads * sizeof(float)>>>(d_intermediate, d_in);
- }
- else
- {
- global_reduce_kernel<<<blocks, threads>>>(d_intermediate, d_in);
- }
- threads = blocks;
- blocks = 1;
- if (usesShareMemory)
- {
- if (usesShareMemory)
- {
- share_reduce_kernel<<<blocks, threads, threads * sizeof(float)>>>(d_out, d_intermediate);
- }
- else
- {
- global_reduce_kernel<<<blocks, threads>>>(d_out, d_intermediate);
- }
- }
- }
复制代码
最后,在`main`函数中,你定义了一个常量`ARRAY_SIZE`但没有给它赋值。请为它赋予一个合适的值,比如`1000`。修正后的代码如下:
- int main(int argc, char** argv)
- {
- // ...
- const int ARRAY_SIZE = 1000;
- // ...
- }
复制代码
希望这些修正能够解决你遇到的问题。如果还有其他问题,请随时提问!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
|
|