我的下面的代码出现错误,当它运行时,一些图形权重被覆盖,但不应该发生Xa数组(它保留哪些已被访问过)和__syncthreads()函数。 ..有人可以帮忙吗?
struct Node
{
int begin; // begining of the substring
int num; // size of the sub-string
};
__global__ void BFS (Node *Va, int *Ea, bool *Fa, bool *Xa, int *Ca, bool *parada)
{
int tid = threadIdx.x;
if (Fa[tid] == true && Xa[tid] == false)
{
Fa[tid] = false;
__syncthreads();
// Va begin is where it's edges' subarray begins, Va is it's
// number of elements
for (int i = Va[tid].begin; i < (Va[tid].begin + Va[tid].num); i++)
{
int nid = Ea[i];
if (Xa[nid] == false)
{
Ca[nid] = Ca[tid] + 1;
Fa[nid] = true;
*parada = true;
}
}
Xa[tid] = true;
}
}
// The BFS frontier corresponds to all the nodes being processed
// at the current level.
int main()
{
//descrição do grafo
struct Node node[4];
node[0].begin=0;
node[0].num=2;
node[1].begin=1;
node[1].num=0;
node[2].begin=2;
node[2].num=2;
node[3].begin=1;
node[3].num=0;
int edges[]={1,2,3,1};
bool frontier[4]={false};
bool visited[4]={false};
int custo[4]={0};
int source=0;
frontier[source]=true;
Node* Va;
cudaMalloc((void**)&Va,sizeof(Node)*4);
cudaMemcpy(Va,node,sizeof(Node)*4,cudaMemcpyHostToDevice);
int* Ea;
cudaMalloc((void**)&Ea,sizeof(Node)*4);
cudaMemcpy(Ea,edges,sizeof(Node)*4,cudaMemcpyHostToDevice);
bool* Fa;
cudaMalloc((void**)&Fa,sizeof(bool)*4);
cudaMemcpy(Fa,frontier,sizeof(bool)*4,cudaMemcpyHostToDevice);
bool* Xa;
cudaMalloc((void**)&Xa,sizeof(bool)*4);
cudaMemcpy(Xa,visited,sizeof(bool)*4,cudaMemcpyHostToDevice);
int* Ca;
cudaMalloc((void**)&Ca,sizeof(int)*4);
cudaMemcpy(Ca,custo,sizeof(int)*4,cudaMemcpyHostToDevice);
dim3 threads(4,1,1);
bool para;
bool* parada;
cudaMalloc((void**)¶da,sizeof(bool));
printf("\n");
int n=1;
do{
para=false;
cudaMemcpy(parada,¶,sizeof(bool),cudaMemcpyHostToDevice);
BFS <<<1,threads>>>(Va,Ea,Fa,Xa,Ca,parada);
CUT_CHECK_ERROR("kernel1 execution failed");
cudaMemcpy(¶,parada,sizeof(bool),cudaMemcpyDeviceToHost);
printf("Run number: %d >> ",n);
cudaMemcpy(custo,Ca,sizeof(int)*4,cudaMemcpyDeviceToHost);
for(int i=0;i<4;i++)
printf("%d ",custo[i]);
printf("\n");
n++;
}while(para);
printf("\nFinal:\n");
cudaMemcpy(custo,Ca,sizeof(int)*4,cudaMemcpyDeviceToHost);
for(int i=0;i<4;i++)
printf("%d ",custo[i]);
printf("\n");
}
答案 0 :(得分:5)
该设备代码中存在许多相当大的缺陷。首先,您在Xa
和Ca
都有记忆比赛。其次,你有一个有条件执行的__syncthreads()
调用,这是非法的,并且如果由线程扭曲执行,可能导致内核挂起,其中可能发生围绕调用的任何分支差异。
您正在使用的算法结构可能在CUDA上不正确,即使您使用原子内存访问函数来消除代码中发布的最差的pf read-after-write比赛。使用原子内存访问将有效地序列化代码并降低成本。
对CUDA的广度优先搜索不是一个未解决的问题。如果你想搜索它们,有很多关于实现的好文章。如果你还没有看过,我会推荐High Performance and Scalable GPU Graph Traversal。这些作者实现的代码也可以从here下载。