Algorithm GPU的合并排序
我正在尝试使用opencl包装器实现合并排序 问题是,每个过程都需要不同的索引算法来访问线程的内存 有关这方面的一些信息:Algorithm GPU的合并排序,algorithm,opencl,gpu,mergesort,Algorithm,Opencl,Gpu,Mergesort,我正在尝试使用opencl包装器实现合并排序 问题是,每个过程都需要不同的索引算法来访问线程的内存 有关这方面的一些信息: First pass(numbers indicate elements and arrows indicate sorting) 0<-->1 2<--->3 4<--->5 6<--->7 group0 group1 group2 group3 ===>1 thread per group,
First pass(numbers indicate elements and arrows indicate sorting)
0<-->1 2<--->3 4<--->5 6<--->7
group0 group1 group2 group3 ===>1 thread per group, N/2 groups total
Second pass(all parallel)
0<------>2 4<------>6
1<------->3 5<------->7
group0 group1 ========> 2 threads per group, N/4 groups
Next pass
0<--------------->4 8<------------------>12
1<--------------->5 9<------------------->13
2<--------------->6 10<---------------->14
3<--------------->7 11<--------------->15
group0 group1 ===>4 threads per group
but N/8 groups
那么,在内核字符串中,它可以是
int i=get_global_id(0);
int compareId1=( i/( pow(2,passN) ) ) * pow(2,passN+1) + i%( pow(2, passN) );
int compareId2=compareId1+pow(2,passN);
if(compareId1!=compareId2)
{
if(A[compareId1]>A[compareId2])
{
xorSwapIdiom(A,compareId1,compareId2,B);
}
else
{
streamThrough(A,compareId1,compareId2,B);
}
}
else
{
// this can happen only for the first pass
// needs a different kernel structure for that
}
but Im not sure.
问题:在满足“不同组之间不进行比较”条件的情况下,您能否给出哪些内存访问模式不会泄漏的说明
我已经多次需要硬重设我的电脑,尝试不同的算法(内存泄漏、黑屏、崩溃、重启),这是最后一次,我担心它会使整个操作系统崩溃
我已经尝试了一个更简单的版本,每次通过的线程数减少了,但性能不好
编辑:我尝试了上面的代码,它按逆序排列数组。但不是随机数组。如果排序算法本身不是主要的,请尝试双音排序。它从本地内存中受益匪浅&您不需要编写代码,有很多示例可用。您选择合并排序的原因纯粹是学术性的吗?这似乎不是最适合使用的算法。我只是尝试一些统一的传递类型排序,让每个核心做等量的工作。不是学术性的。只是尝试一下,如果我可以帮助任何数据库排序行动与此。我也会研究双音排序。
A[1]<---->A[2] and A[4]<----->A[8]
Pass n: global id(i): 0,1, 2,3 4,5 , ... to compare id 0,1 4,5 8,9
looks like compare id1=(i/2)*4+i%2
Pass n+1: global id(i): 0,1,2,3, 4,5,6,7, ... to compare id 0,1,2,3, 8,9,10,11, 16,17
looks like compare id=(i/4)*8+i%4
Pass n+2: global id(i): 0,1,2,3,... 8,9,10,... to compare id 0,1,2,3,... 16,17,18,...
looks like compare id=(i/8)*16+i%8
compare id1 = ( i/( pow(2,passN) ) ) * pow(2,passN+1) + i%( pow(2, passN) )
compare id2 = compare id1 + pow(2,passN)
int i=get_global_id(0);
int compareId1=( i/( pow(2,passN) ) ) * pow(2,passN+1) + i%( pow(2, passN) );
int compareId2=compareId1+pow(2,passN);
if(compareId1!=compareId2)
{
if(A[compareId1]>A[compareId2])
{
xorSwapIdiom(A,compareId1,compareId2,B);
}
else
{
streamThrough(A,compareId1,compareId2,B);
}
}
else
{
// this can happen only for the first pass
// needs a different kernel structure for that
}
but Im not sure.