我试图使用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, 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
因此,子组的元素不能在另一个组的元素之间进行任何比较。
我不能简单地做
A[i]<---->A[i+1] or A[i]<---->A[i+4]
因为这些涵盖了
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.
问题:在满足“不同群体之间无比较”条件的同时,您能否说明哪些内存访问模式不会泄漏?
需要多次硬复位我的电脑,尝试不同的algortihms(内存泄露,黑屏,崩溃,重启),这是最后一次,我担心它会崩溃整个操作系统。
我已经尝试了一个更简单的版本,每次传递的线程数越来越少,性能有些不好。
编辑:我尝试了上面的代码,它对反向排序的数组进行了排序。但不是随机数组。