Algorithm GPU的合并排序

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,

我正在尝试使用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
那么,在内核字符串中,它可以是

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.