多线程对800万个数据进行排序

分8个线程对800万个数据分别排序,等所有线程排完序之后,进行简单的多路归并。这和外排的多路归并是一样的,也可以使用优化的胜者树算法。

#include <iostream>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>
#include <sys/time.h>
using namespace std;
#define NTHR   8                /* number of threads */
#define NUMNUM 8000000L         /* number of numbers to sort */
#define TNUM   (NUMNUM/NTHR)    /* number to sort per thread */

int nums[NUMNUM];
int snums[NUMNUM];

pthread_barrier_t b;

void HeapAdjust(int *a, int i, int size)
{
    int lchild = 2*i;
    int rchild = 2*i + 1;
    int max = i;
    if(i <=size/2)
    {
        if(lchild <=size && a[lchild] > a[max] )
        {
            max = lchild;
        }
        if(rchild <=size && a[rchild] > a[max])
        {
            max = rchild;
        }
        if(max != i)
        {
            swap(a[i], a[max]);
            HeapAdjust(a, max, size);
        }
    }
}

void BuildHeap(int *a, int size)
{
    int i;
    for(i = size/2; i >= 1; i--)
    {
        HeapAdjust(a, i, size);
    }
}

void HeapSort(int *a, int size)
{
    int i;
    BuildHeap(a, size);
    for(i=size;i>=1;i--)
    {
        swap(a[1], a[i]);
        HeapAdjust(a, 1, i-1);
    }
}

/*
 * Worker thread to sort a portion of the set of numbers.
 */
void * thr_fn(void *arg)
{
    long idx = (long)arg;

    HeapSort(&nums[idx], TNUM);
    pthread_barrier_wait(&b);

    /*
     * Go off and perform more work ...
     */
    return((void *)0);
}

/*
 * Merge the results of the individual sorted ranges.
 */
void merge()
{
    long    idx[NTHR];
    long    i, minidx, sidx, num;

    for (i = 0; i < NTHR; i++)
        idx[i] = i * TNUM;
    for (sidx = 0; sidx < NUMNUM; sidx++) {
        num = LONG_MAX;
        for (i = 0; i < NTHR; i++) {
            if ((idx[i] < (i+1)*TNUM) && (nums[idx[i]] < num)) {
                num = nums[idx[i]];
                minidx = i;
            }
        }
        snums[sidx] = nums[idx[minidx]];
        idx[minidx]++;
    }
}

int
main()
{
    unsigned long   i;
    struct timeval  start, end;
    long long       startusec, endusec;
    double          elapsed;
    int             err;
    pthread_t       tid;

    /*
     * Create the initial set of numbers to sort.
     */
    srandom(1);
    for (i = 0; i < NUMNUM; i++)
        nums[i] = random();

    /*
     * Create 8 threads to sort the numbers.
     */
    gettimeofday(&start, NULL);
    pthread_barrier_init(&b, NULL, NTHR+1);
    for (i = 0; i < NTHR; i++) {
        err = pthread_create(&tid, NULL, thr_fn, (void *)(i * TNUM));
        if (err != 0)
            cout<<"can‘t create thread";
    }
    pthread_barrier_wait(&b);
    merge();
    gettimeofday(&end, NULL);

    /*
     * Print the sorted list.
     */
    startusec = start.tv_sec * 1000000 + start.tv_usec;
    endusec = end.tv_sec * 1000000 + end.tv_usec;
    elapsed = (double)(endusec - startusec) / 1000000.0;
    for (i = 0; i < NUMNUM; i++)
        cout<<snums[i]<<"\n";
    cout<<"sort took seconds"<<elapsed;
    exit(0);
}

Reference

[1].编程珠玑. P5

[2].http://blog.chinaunix.net/uid-25324849-id-2182916.html

时间: 2024-10-25 10:14:40

多线程对800万个数据进行排序的相关文章

100万个数据,数据值在0~65535之间,请用尽可能少的内存和最快的速度从小到大排序

场景说明:100万个数据,数据值在0~65535之间,请用尽可能少的内存和最快的速度从小到大排序 voidsort(int* array, int n) { //n的值在100万左右 //你的实现 } 我们首先观察到所有的数据已经保存到了array数组中,现在我们需要做的就是将数组中的元素排序.现在我们把数组中的元素提取出来比如是3,然后我们提取出数组下标是3的元素,保存到临时空间,通过负数来计算个数: void sort(int* array, int n) {     int tmp=0;

对一千万条数据进行排序---编程珠玑第二版 第一章

本书第一章提出了一个看似简单的问题,有最多1000万条不同的整型数据存在于硬盘的文件中,如何在1M内存的情况下对其进行尽可能快的排序. 每个数字用4byte,1M即可存储250 000个数据,显然,只要每次对250 000个数据排序,写入到文件中即可,重复40次. 那么如何选出每次遍历的二十五万条数据呢?有如下两个策略: 1.对一千万条数据遍历40次,第i次遍历时,判断数是否属于[i*250000,i*250000+249999),如果是,则读入内存,当第i次遍历完成时,内 存中有了二十五万条数

JavaScript如何一次性展示几万条数据

有一位同事跟大家说他在网上看到一道面试题:"如果后台传给前端几万条数据,前端怎么渲染到页面上?",如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成html插到页面上:有的说应该用分页来处理:还有的说这个面试官是个白痴, 哪有后台传几万条数据给前端这种情况的:我仔细思考了一下,先不论后端到底会不会白痴到传几万条数据给前端,假如真碰到这种情况,那么如果前端获取到数据以后, 直接将数据转换成html字符串,通过DOM操作插入到页面,势必导

如何在800万公众号中脱颖而出

根据微信官方最新披露的数据,微信公众号数量已经突破800万,每天还在以1.5万的速度在增加.中国在册企业数量4000万,开通微信公众号的企业越来越多,微信公众号已经基本进入标配期. 用户凭什么在800万公众号中看上你? 在标配期,我的判断是:微信的数字红利期结束了,价值红利期刚刚开始. 因为: 用户早已理性了,不会随便去关注一堆跟自己八竿子打不着的账号,更何况现在大部分账号惨不忍睹.每个用户在消费周期里能够阅读和使用的公众号的数量是极其有限的.比如用户买你衣服后,至少要两月以后才会再次购买,这个

极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

原文:极限挑战-C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方法所耗费的时间. 本实验中所用到工具为VS2008和SQL SERVER 2000.SQL SERVER 2008,分别使用5中方法将100万条数据导入SQL 2000与SQL 2008中,实验环境是DELL 2850双2.0GCPU,2G内存的服务器.感兴趣的朋友可以下载源代码自己验证一下所用时间

Oracle笔记(四) 简单查询、限定查询、数据的排序

Oracle笔记(四) 简单查询.限定查询.数据的排序 一.简单查询 SQL(Structured Query Language) 结构化查询语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统.ANSI(美国国家标准学会)声称,SQL是关系数据库管理系统的标准语言. Oracle数据库之所以发展的很好,主要也是因为Oracle是全世界最早采用SQL语句的数据库产品. SQL功能强大,概括起来,它可以分成以下几组: DML(Data Manipulation La

印度人还上不起网?每天超过800万人在火车站使用免费WiFi

印度人还上不起网?早在2015年,谷歌推出了向印度火车站免费提供WiFi的举措,今天这家美国科技巨头宣布该计划已经超过了400个车站的目标,现在每天吸引了超过800万用户. 当Google透露每个月有超过八百万人使用基于铁路的无线网络时,谷歌对该计划的覆盖范围进行了深入的了解.该公司平均说,用户每次会话消耗350MB数据,其中一半通过WiFi程序每天至少两次上网. 在另一个规模的迹象中,谷歌今年早些时候开始通过为价格提供高速连接来实现该计划的货币化.标准选项包括为Google及其合作伙伴(包括印

(转)Python网络爬虫实战:世纪佳缘爬取近6万条数据

又是一年双十一了,不知道从什么时候开始,双十一从“光棍节”变成了“双十一购物狂欢节”,最后一个属于单身狗的节日也成功被攻陷,成为了情侣们送礼物秀恩爱的节日. 翻着安静到死寂的聊天列表,我忽然惊醒,不行,我们不能这样下去,光羡慕别人有什么用,我们要行动起来,去找自己的幸福!!! 我也想“谈不分手的恋爱” !!!内牛满面!!! 注册登陆一气呵成~ 筛选条件,嗯...性别女,年龄...18到24岁,身高嘛,无所谓啦,就按默认155-170吧,地区...嗯北京好,北京近一点,照片?那肯定要啊,必须的!!

Delphi中多线程用消息实现VCL数据同步显示

Delphi中多线程用消息实现VCL数据同步显示 Lanno Ckeeke 2006-5-12 概述: delphi中严格区分主线程和子主线程,主线程负责GUI的更新,子线程负责数据运算,当数据运行完毕后,子线程可以向主线程式发送消息,以便通知其将VCL中的数据更新. 实现: 关键在于消息的发送及接收.在消息结构Tmessage中wParam和lParam类型为Longint,而指针类型也定义为Longint,可以通过此指针来传递自己所感兴趣的数据.如传递字符数组: 数组定义: const MA