当CUDA线程在同一个循环中,并且我们需要同步它们以仅执行有限的部分时,如何同步它们
我已经写了一些代码,现在我想在CUDA GPU上实现这一点,但我对同步还不熟悉。下面我将介绍代码,我希望LOOP1由所有线程执行(因此我希望这一部分利用CUDA,其余部分(LOOP1的另一部分)仅由单个线程执行当CUDA线程在同一个循环中,并且我们需要同步它们以仅执行有限的部分时,如何同步它们,cuda,parallel-processing,gpu,Cuda,Parallel Processing,Gpu,我已经写了一些代码,现在我想在CUDA GPU上实现这一点,但我对同步还不熟悉。下面我将介绍代码,我希望LOOP1由所有线程执行(因此我希望这一部分利用CUDA,其余部分(LOOP1的另一部分)仅由单个线程执行 do{ point_set = master_Q[(*num_mas) - 1].q; List* temp = point_set; List* pa = point_set; if(master_Q[num_mas[0] - 1].max) max_level
do{
point_set = master_Q[(*num_mas) - 1].q;
List* temp = point_set;
List* pa = point_set;
if(master_Q[num_mas[0] - 1].max)
max_level = (int) (ceilf(il2 * log(master_Q[num_mas[0] - 1].max)));
*num_mas = (*num_mas) - 1;
while(point_set){
List* insert_ele = temp;
while(temp){
insert_ele = temp;
if((insert_ele->dist[insert_ele->dist_index-1] <= pow(2, max_level-1)) || (top_level == max_level)){
if(point_set == temp){
point_set = temp->next;
pa = temp->next;
}
else{
pa->next = temp->next;
}
temp = NULL;
List* new_point_set = point_set;
float maximum_dist = 0;
if(parent->p_index != insert_ele->point_index){
List* tmp = new_point_set;
float *b = &(data[(insert_ele->point_index)*point_len]);
**LOOP 1:** while(tmp){
float *c = &(data[(tmp->point_index)*point_len]);
float sum = 0.;
for(int j = 0; j < point_len; j+=2){
float d1 = b[j] - c[j];
float d2 = b[j+1] - c[j+1];
d1 *= d1;
d2 *= d2;
sum = sum + d1 + d2;
}
tmp->dist[tmp->dist_index] = sqrt(sum);
if(maximum_dist < tmp->dist[tmp->dist_index])
maximum_dist = tmp->dist[tmp->dist_index];
tmp->dist_index = tmp->dist_index+1;
tmp = tmp->next;
}
max_distance = maximum_dist;
}
while(new_point_set || insert_ele){
List* far, *par, *tmp, *tmp_new;
far = NULL;
tmp = new_point_set;
tmp_new = NULL;
float level_dist = pow(2, max_level-1);
float maxdist = 0, maxp = 0;
while(tmp){
if(tmp->dist[(tmp->dist_index)-1] > level_dist){
if(maxdist < tmp->dist[tmp->dist_index-1])
maxdist = tmp->dist[tmp->dist_index-1];
if(tmp == new_point_set){
new_point_set = tmp->next;
par = tmp->next;
}
else{
par->next = tmp->next;
}
if(far == NULL){
far = tmp;
tmp_new = far;
}
else{
tmp_new->next = tmp;
tmp_new = tmp;
}
if(parent->p_index != insert_ele->point_index)
tmp->dist_index = tmp->dist_index - 1;
tmp = tmp->next;
tmp_new->next = NULL;
}
else{
par = tmp;
if(maxp < tmp->dist[(tmp->dist_index)-1])
maxp = tmp->dist[(tmp->dist_index)-1];
tmp = tmp->next;
}
}
if(0 == maxp){
tmp = new_point_set;
aloc_mem[*tree_index].p_index = insert_ele->point_index;
aloc_mem[*tree_index].no_child = 0;
aloc_mem[*tree_index].level = max_level--;
parent->children_index[parent->no_child++] = *tree_index;
parent = &(aloc_mem[*tree_index]);
tree_index[0] = tree_index[0]+1;
while(tmp){
aloc_mem[*tree_index].p_index = tmp->point_index;
aloc_mem[(*tree_index)].no_child = 0;
aloc_mem[(*tree_index)].level = master_Q[(*cur_count_Q)-1].level;
parent->children_index[parent->no_child] = *tree_index;
parent->no_child = parent->no_child + 1;
(*tree_index)++;
tmp = tmp->next;
}
cur_count_Q[0] = cur_count_Q[0]-1;
new_point_set = NULL;
}
master_Q[*num_mas].q = far;
master_Q[*num_mas].parent = parent;
master_Q[*num_mas].valid = true;
master_Q[*num_mas].max = maxdist;
master_Q[*num_mas].level = max_level;
num_mas[0] = num_mas[0]+1;
if(0 != maxp){
aloc_mem[*tree_index].p_index = insert_ele->point_index;
aloc_mem[*tree_index].no_child = 0;
aloc_mem[*tree_index].level = max_level;
parent->children_index[parent->no_child++] = *tree_index;
parent = &(aloc_mem[*tree_index]);
tree_index[0] = tree_index[0]+1;
if(maxp){
int new_level = ((int) (ceilf(il2 * log(maxp)))) +1;
if (new_level < (max_level-1))
max_level = new_level;
else
max_level--;
}
else
max_level--;
}
if( 0 == maxp )
insert_ele = NULL;
}
}
else{
if(NULL == temp->next){
master_Q[*num_mas].q = point_set;
master_Q[*num_mas].parent = parent;
master_Q[*num_mas].valid = true;
master_Q[*num_mas].level = max_level;
num_mas[0] = num_mas[0]+1;
}
pa = temp;
temp = temp->next;
}
}
if((*num_mas) > 1){
List *temp2 = master_Q[(*num_mas)-1].q;
while(temp2){
List* temp3 = master_Q[(*num_mas)-2].q;
master_Q[(*num_mas)-2].q = temp2;
if((master_Q[(*num_mas)-1].parent)->p_index != (master_Q[(*num_mas)-2].parent)->p_index){
temp2->dist_index = temp2->dist_index - 1;
}
temp2 = temp2->next;
master_Q[(*num_mas)-2].q->next = temp3;
}
num_mas[0] = num_mas[0]-1;
}
point_set = master_Q[(*num_mas)-1].q;
temp = point_set;
pa = point_set;
parent = master_Q[(*num_mas)-1].parent;
max_level = master_Q[(*num_mas)-1].level;
if(master_Q[(*num_mas)-1].max)
if( max_level > ((int) (ceilf(il2 * log(master_Q[(*num_mas)-1].max)))) +1)
max_level = ((int) (ceilf(il2 * log(master_Q[(*num_mas)-1].max)))) +1;
num_mas[0] = num_mas[0]-1;
}
}while(*num_mas > 0);
do{
点集=master\u Q[(*num\u mas)-1].Q;
列表*温度=点集;
列表*pa=点集;
if(主控Q[num\u mas[0]-1].max)
max_level=(int)(ceilf(il2*log(master_Q[num_mas[0]-1].max));
*num_mas=(*num_mas)-1;
while(点集){
列表*插入_ele=temp;
while(临时){
插入_ele=温度;
如果((插入元素->距离[插入元素->距离索引-1]下一步;
pa=温度->下一步;
}
否则{
pa->next=temp->next;
}
温度=零;
列表*新建点集=点集;
浮动最大距离=0;
如果(父级->p_索引!=插入元素->点索引){
列表*tmp=新点集;
浮点*b=&(数据[(插入元素->点索引)*点长度];
**循环1:*while(tmp){
浮点*c=&(数据[(tmp->点索引)*点长度];
浮点数和=0。;
对于(int j=0;jdist[tmp->dist_index]=sqrt(总和);
if(最大距离dist[tmp->dist\u索引])
最大距离=tmp->dist[tmp->dist\u index];
tmp->dist_index=tmp->dist_index+1;
tmp=tmp->next;
}
最大距离=最大距离;
}
while(新点集插入元素){
列表*far、*par、*tmp、*tmp\U新;
远=零;
tmp=新点集;
tmp_new=NULL;
浮动液位距离=功率(2,最大液位1);
float maxdist=0,maxp=0;
while(tmp){
如果(tmp->dist[(tmp->dist\u index)-1]>级别\u dist){
if(maxdistdist[tmp->dist\u index-1])
maxdist=tmp->dist[tmp->dist_index-1];
如果(tmp==新点集){
新建点集=tmp->next;
PAR=TMP->下一步;
}
否则{
par->next=tmp->next;
}
if(far==NULL){
far=tmp;
tmp_new=far;
}
否则{
tmp_new->next=tmp;
tmp_new=tmp;
}
如果(父级->p_索引!=插入元素->点索引)
tmp->dist_index=tmp->dist_index-1;
tmp=tmp->next;
tmp_new->next=NULL;
}
否则{
PAR=TMP;
if(maxpdist[(tmp->dist_index)-1])
maxp=tmp->dist[(tmp->dist_index)-1];
tmp=tmp->next;
}
}
如果(0==maxp){
tmp=新点集;
aloc_mem[*树索引].p_索引=插入元素->点索引;
aloc_mem[*树索引].无子项=0;
aloc_mem[*树索引].level=max_level--;
父级->子级索引[父级->无子级+]=*树级索引;
父项=&(aloc_mem[*树索引]);
树索引[0]=树索引[0]+1;
while(tmp){
aloc_mem[*树索引].p_索引=tmp->点索引;
aloc_mem[(*树索引)]。无子项=0;
aloc_mem[(*树索引)]。级别=主控_Q[(*当前计数_Q)-1]。级别;
父级->子级索引[父级->无子级]=*树级索引;
父级->无子级=父级->无子级+1;
(*树索引)++;
tmp=tmp->next;
}
cur_count_Q[0]=cur_count_Q[0]-1;
新点集=空;
}
master_Q[*num_mas].Q=far;
master_Q[*num_mas].父项=父项;
master_Q[*num_mas].valid=true;
master_Q[*num_mas].max=maxdist;
master_Q[*num_mas]。级别=最高级别;
num_mas[0]=num_mas[0]+1;
如果(0!=maxp){
aloc_mem[*树索引].p_索引=插入元素->点索引;
aloc_mem[*树索引].无子项=0;
aloc_mem[*树索引].level=max_level;
父级->子级索引[父级->无子级+]=*树级索引;
父项=&(aloc_mem[*树索引]);
树索引[0]=树索引[0]+1;
if(maxp){
intnew_level=((int)(celf(il2*log(maxp)))+1;
如果(新级别<(最高级别1))
最大水平=新水平;
其他的
最大水平--;
}
其他的
最大水平--;
}
如果(0==maxp)
插入_ele=NULL;
}
}
否则{
如果(空==临时->下一步){
master_Q[*num_mas].Q=点集;
master_Q[*num_mas].父项=父项;
master_Q[*num_mas].valid=true;
master_Q[*num_mas]。级别=最高级别;
num_mas[0]=num_mas[0]+1;
}
pa=温度;
温度=温度->下一步;
}
}
如果((*num_mas)>1){
List*temp2=master_Q[(*num_mas)-1].Q;
while(temp2){
List*temp3=master_Q[(*num_mas)-2].Q;
大师Q[(*num_mas)-2].Q=temp2;
如果((主控Q[(*num\u mas)-1].parent)->p\u index!=(主控Q[(*num\u mas)-2].parent)->p\u index){
temp2->dist_index=temp2->dist_index-1;
}
temp2=temp2->next;
掌握Q[(*num\u mas)-2].Q->next=temp3;
}
num_mas[0]=num_mas[0]-1;
}
点集=master\u Q[(*num\u mas)-1].Q;
温度=点集;
pa=点集;
parent=master_Q[(*num_mas)-1]。parent;
最大等级=主等级Q[(*num\u mas)-1]。等级;
如果(主数量Q[(*num\u mas)-1].max)
if(max_level>((int)(celf(il2*log(master_Q[(*num_mas)-1.max)))+1)
最大级别=((int)(ceilf(il2*log(master_Q[(*num\u mas)-1].max))+1;
num_mas[0]=num_mas[0]-1;
}
}而(*num_mas>0);
如果您希望单个内核只在块内的单个线程上执行部分代码,请使用If语句只为单个线程IDX执行部分代码,然后进行barrier同步。也许您应该尝试编写内核并发布该内核以供人们查看。您的格式严重损坏。请确保确定你的代码是我的