bitonic_sort using mpi in c

来源:互联网 发布:淘宝上的组装电脑 编辑:程序博客网 时间:2024/04/30 09:59

最近用mpi(消息传递接口,基于分布式存储机制的)实现了下bitonic_sort,理论上它的

时间复杂度只有O(lgn * lgn),但是需要用到n/2个比较器,,(从这里可以发现,如果用串行实现,复杂度就是O(n*lgn*lgn))所以可扩展性非常的差,一般也就没什么实际意义,在目前的这种应用上。不过我还是根据自己对这个算法的理解,用mpi实现了一把,下面陈述之:
首先假设有n=2^d 个数待排序,如果n不是2的次方的话,也是ok的,不过某些个线程,

和某些次比较可能是空操作而已,因此为了方便起见让n=2^d,p为线程数,每一个线程

保存2个整数,即p=n/2。线程编号id从0,...p-1
first = 1;next = 1;//这两个变量与id号的关联是关键
for(i=0;i<d;i++)//需要d躺归并
{
    if(i>0)//第一躺方向刚好相反,因为2组线程都是有序的
    {
       partner = id^first;
       first = first<<1 + 1;
       //让编号为id,partner的线程先交换各自其中一个数字,然后比较,再把比较 

     //后的结果返回回来
    }
    next = first>>2 - first>>3;//取first右移2位后的最高位
    for(j=i-1;j>0;j--)//第i部的归并的后续操作
    {
       partner = id^next;
       //id与partner进程通信比较返回操作
       next = next>>1;
    }
    //一个线程中2个数的排序,每次归并的最后一次操作
    if(data[1]<data[0])
        swap(data,1,0);
}
这个就是此算法的主要框架,由于本人的这个实现用到了很多MPI_Send,MPI_Recv等通信

操作,所以当测试32个数排序时,时间都已经达到了0.5ms左右,可见通信时间占了绝大

多数。然而当时我想,既然这个算法的扩展性不好,因此可以在每次线程中保留一份完

整的数据,这样在比较过程中就可以省略掉数据的通信交换了,应该可以提速不少,只

是当每一个线程通过比较后,改变了原来2个数的位置后,需要把这个事实广播给其他所

有线程,让他们也改变相应的位置,始终保持所有线程的数据都同步,这个需要O(lgn)

的时间,因此如果广播太频繁的话,这个改变已经偏离了bitonic_sort的初衷,尽管如

此,时间肯定是会得到提升的。

原创粉丝点击