C++ CUDA共享内存编程不工作
全部: 我正在学习共享内存如何加速GPU编程过程。我使用下面的代码来计算每个元素的平方值加上其左右邻域平均值的平方值。 但是,代码运行时,结果并不像预期的那样 打印出来的前10个结果是0,1,2,3,4,5,6,7,8,9,而我预期的结果是25,2,8,18,32,50,72,98128162 代码如下所示,参考: 你能告诉我哪个部分出了问题吗?非常感谢你的帮助C++ CUDA共享内存编程不工作,c++,cuda,gpu,C++,Cuda,Gpu,全部: 我正在学习共享内存如何加速GPU编程过程。我使用下面的代码来计算每个元素的平方值加上其左右邻域平均值的平方值。 但是,代码运行时,结果并不像预期的那样 打印出来的前10个结果是0,1,2,3,4,5,6,7,8,9,而我预期的结果是25,2,8,18,32,50,72,98128162 代码如下所示,参考: 你能告诉我哪个部分出了问题吗?非常感谢你的帮助 #include <stdio.h> #include <stdlib.h> #include <ios
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cuda.h>
const int N=1024;
__global__ void compute_it(float *data)
{
int tid = threadIdx.x;
__shared__ float myblock[N];
float tmp;
// load the thread's data element into shared memory
myblock[tid] = data[tid];
// ensure that all threads have loaded their values into
// shared memory; otherwise, one thread might be computing
// on unitialized data.
__syncthreads();
// compute the average of this thread's left and right neighbors
tmp = (myblock[tid>0?tid-1:(N-1)] + myblock[tid<(N-1)?tid+1:0]) * 0.5f;
// square the previousr result and add my value, squared
tmp = tmp*tmp + myblock[tid]*myblock[tid];
// write the result back to global memory
data[tid] = myblock[tid];
__syncthreads();
}
int main (){
char key;
float *a;
float *dev_a;
a = (float*)malloc(N*sizeof(float));
cudaMalloc((void**)&dev_a,N*sizeof(float));
for (int i=0; i<N; i++){
a [i] = i;
}
cudaMemcpy(dev_a, a, N*sizeof(float), cudaMemcpyHostToDevice);
compute_it<<<N,1>>>(dev_a);
cudaMemcpy(a, dev_a, N*sizeof(float), cudaMemcpyDeviceToHost);
for (int i=0; i<10; i++){
std::cout<<a [i]<<",";
}
std::cin>>key;
free (a);
free (dev_a);
#包括
#包括
#包括
#包括
常数int N=1024;
__全局无效计算(浮点*数据)
{
int tid=threadIdx.x;
__共享\uuuuuu浮点myblock[N];
浮动tmp;
//将线程的数据元素加载到共享内存中
myblock[tid]=数据[tid];
//确保所有线程都已将其值加载到
//共享内存;否则,一个线程可能正在计算
//关于统一化数据。
__同步线程();
//计算该线程左右邻域的平均值
tmp=(myblock[tid>0?tid-1:(N-1)]+myblock[tid内核代码中最直接的问题之一是:
data[tid] = myblock[tid];
我想你可能是这个意思:
data[tid] = tmp;
此外,每个线程启动1024个块。这不是使用GPU的特别有效的方法,它意味着每个线程块中的tid
变量为0(并且只有0,因为每个线程块只有一个线程)
这种方法存在许多问题,但这里会遇到一个直接的问题:
tmp = (myblock[tid>0?tid-1:(N-1)] + myblock[tid<31?tid+1:0]) * 0.5f;
正如Kristof所指出的,我认为你会得到一些接近你想要的东西,但是如果没有对代码进行其他更改,你将无法方便地将其扩展到N=1024以上
这一行代码也不正确:
free (dev_a);
由于dev_a
是使用cudamaloc
在设备上分配的,因此您应该这样释放它:
cudaFree (dev_a);
内核代码中最直接的问题之一是:
data[tid] = myblock[tid];
我想你可能是这个意思:
data[tid] = tmp;
此外,每个线程启动1024个块。这不是使用GPU的特别有效的方法,它意味着每个线程块中的tid
变量为0(并且只有0,因为每个线程块只有一个线程)
这种方法存在许多问题,但这里会遇到一个直接的问题:
tmp = (myblock[tid>0?tid-1:(N-1)] + myblock[tid<31?tid+1:0]) * 0.5f;
正如Kristof所指出的,我认为你会得到一些接近你想要的东西,但是如果没有对代码进行其他更改,你将无法方便地将其扩展到N=1024以上
这一行代码也不正确:
free (dev_a);
由于dev_a
是使用cudamaloc
在设备上分配的,因此您应该这样释放它:
cudaFree (dev_a);
由于每个块只有一个线程,因此tid将始终为0
尝试以下方式启动内核:
计算it(开发a)
而不是
compute_it(dev_a);因为每个块只有一个线程,所以tid始终为0
尝试以下方式启动内核:
计算it(开发a)
而不是
计算it(开发a)是的,克里斯托夫,我的代码中的顺序是错误的,而且我引用的原始代码根本没有将tmp值分配给数据集。更改这两个代码后,代码工作。是的,克里斯托夫,我的代码中的顺序是错误的,而且我引用的原始代码根本没有将tmp值分配给数据集。更改这两个代码后,t代码是有效的。谢谢你详细的回答,罗伯特。它确实帮助我更好地理解层次结构,并学习一些有益的编程行为。我按照你和克里斯托夫的建议修复了代码。谢谢你详细的回答,罗伯特。它确实帮助我更好地理解层次结构,并学习一些有益的东西l编程行为。我已经按照你和克里斯托夫的建议修复了代码。