电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> 电脑硬件>>双核CPU与单核CPU在快速排序以及多任务下的效率测试比较:

双核CPU与单核CPU在快速排序以及多任务下的效率测试比较

来源:drzhouweiming的专栏 | 2007-3-19 | (有4141人读过)

为了试验一下多核CPU上排序算法的效率,得比较单任务情况下和多任务并行排序算法的差距,因此选用快速排序算法来进行比较。 
测试环境:双核CPU 2.66GHZ 
          单核CPU 2.4GHZ 
  
以下是一个快速排序算法的源代码: 
UINTSplit(void **ppData, UINTuStart, UINTuEnd, 
                     COMPAREFUNCCompareFunc) 

    void *pSelData; 
    UINTuLow; 
    UINTuHigh; 
  
    uLow = uStart; 
    uHigh = uEnd; 
  
    pSelData = ppData[uLow]; 
    while ( uLow < uHigh ) 
    { 
        while ( (*CompareFunc)(ppData[uHigh], pSelData) > 0  
            && uLow != uHigh ) 
        { 
            --uHigh; 
        } 
        if ( uHigh != uLow ) 
        { 
            ppData[uLow] = ppData[uHigh]; 
            ++uLow; 
        } 
  
        while ( (*CompareFunc)( ppData[uLow], pSelData ) < 0 
            && uLow != uHigh ) 
        { 
             ++uLow; 
        } 
        if ( uLow != uHigh ) 
        { 
            ppData[uHigh] = ppData[uLow]; 
            --uHigh; 
        } 
    } 
    ppData[uLow] = pSelData; 
  
    returnuLow; 

  
  
voidQuickSort(void **ppData, UINTuStart, UINTuEnd,  
                        COMPAREFUNCCompareFunc) 

    UINTuMid = Split(ppData, uStart, uEnd, CompareFunc ); 
    if ( uMid > uStart ) 
    { 
        QuickSort(ppData, uStart, uMid - 1, CompareFunc); 
    } 
  
    if ( uEnd > uMid ) 
    { 
        QuickSort(ppData, uMid + 1, uEnd, CompareFunc); 
   } 

  
先测试一下这个快速排序算法排一百万个随机整数所花的时间: 
voidTest_QuickSort(void) 

    UINTi; 
    UINTuCount = 1000000; //1000000个 
  
    srand(time(NULL)); 
    void **pp = (void **)malloc(uCount * sizeof(void *)); 
    for ( i = 0; i < uCount; i++ ) 
    { 
        pp[i] = (void *)(rand() % uCount); 
    } 
  
       clock_tt1 = clock(); 
    QuickSort(pp, 0, uCount-1, UIntCompare); 
       clock_tt2 = clock(); 
  
       printf("QuickSort 1000000 Time %ld\n", t2-t1); 
  
    free(pp); 

  
在双核CPU2.66GHZ机器上运行测试程序,打印出花费的时间约为469 ms  
在单核CPU2.4GHZ机器上运行测试程序,打印出花费时间约为500ms 
可见在双核CPU上运行单任务程序和单核CPU完全是一样的,效率没有任何提高。 
  
下面再来把上面的快速排序程序变成并行的,一个简单的方法就是将要排序的区间分成相同的几个段,然后对每个段进行快速排序,排序完后再使用归并算法将排好的几个区间归并成一个排好序的表,我们先四个线程来进行排序,代码如下: 
  
void ** Merge(void **ppData, UINTuStart, UINTuEnd,  
       void **ppData2, UINTuStart2, UINTuEnd2, COMPAREFUNCcfunc) 

    UINTi, j, k; 
    UINTu1, u2, v1,v2; 
    void **pp1; 
    void **pp2; 
  
    void **pp = (void **)malloc( (uEnd-uStart+1+uEnd2-uStart2+1) * sizeof(void *)); 
    if ( pp == NULL ) 
    { 
        returnNULL; 
    } 
  
    if ( (*cfunc)(ppData2[uStart2], ppData[uStart]) > 0 ) 
    { 
        u1 = uStart; 
        u2 = uEnd; 
        v1 = uStart2;  
        v2 = uEnd2; 
        pp1 = ppData; 
        pp2 = ppData2; 
    } 
    else 
    {         
        u1 = uStart2; 
        u2 = uEnd2; 
        v1 = uStart;  
        v2 = uEnd; 
        pp1 = ppData2; 
        pp2 = ppData; 
    } 
  
    k = 0; 
    pp[k] = pp1[u1]; 
    j = v1; 
    for (i = u1+1; i <= u2; i++ ) 
    { 
        while ( j <= v2 ) 
        { 
            if ( (*cfunc)(pp2[j], pp1[i]) < 0 ) 
           { 
                ++k; 
                pp[k] = pp2[j]; 
                j++; 
            } 
            else 
            { 
                break; 
            } 
        } 
        ++k; 
        pp[k] = pp1[i]; 
    } 
  
    if ( j < v2 ) 
    { 
        for ( i = j; i <= v2; i++) 
        { 
            ++k; 
            pp[k] = pp2[i]; 
        } 
    } 
    returnpp; 

  
typedefstructSORTNODE_st { 
       void **           ppData; 
       UINT             uStart; 
       UINT             uEnd; 
       COMPAREFUNCfunc; 
} SORTNODE; 
  
  
DWORDWINAPIQuickSort_Thread(void *arg) 

       SORTNODE   *pNode = (SORTNODE *)arg; 
       QuickSort(pNode->ppData, pNode->uStart, pNode->uEnd, pNode->func); 
       return 1; 

  
#define THREAD_COUNT    4 
  
INTMQuickSort(void **ppData, UINTuStart, UINTuEnd,  
COMPAREFUNCCompareFunc) 

    void **pp1; 
    void **pp2; 
    void **pp3; 
       INT               i; 
       SORTNODE   Node[THREAD_COUNT]; 
       HANDLE        hThread[THREAD_COUNT]; 
  
       INT        nRet = CAPI_FAILED; 
  
       for ( i = 0; i < THREAD_COUNT; i++) 
       { 
              Node[i].ppData = ppData; 
              if ( i == 0 ) 
              { 
                     Node[i].uStart = uStart; 
              } 
              else 
              { 
                     Node[i].uStart = uEnd * i /THREAD_COUNT + 1;  
              } 
              Node[i].uEnd = uEnd *(i+1) / THREAD_COUNT; 
              Node[i].func = CompareFunc; 
  
              hThread[i] = CreateThread(NULL, 0, QuickSort_Thread, &(Node[i]), 0, NULL); 
       } 
  
       for ( i = 0; i < THREAD_COUNT; i++ ) 
       { 
              WaitForSingleObject(hThread[i], INFINITE); 
       } 
  
  
    pp1 = Merge(ppData, uStart, uEnd/4, ppData, uEnd/4+1, uEnd/2, CompareFunc); 
  
    pp2 = Merge(ppData, uEnd/2+1, uEnd*3/4, ppData, uEnd*3/4+1, uEnd, CompareFunc); 
  
    if ( pp1 != NULL && pp2 != NULL ) 
    { 
        pp3 = Merge(pp1, 0, uEnd/2-uStart, pp2, 0, uEnd - uEnd/2 - 1, CompareFunc); 
  
        if ( pp3 != NULL ) 
        { 
            UINTi; 
           
            for ( i = uStart; i <= uEnd; i++) 
            { 
                ppData[i] = pp3[i-uStart]; 
            } 
            free(pp3); 
            nRet = CAPI_SUCCESS; 
        } 
    } 
    if( pp1 != NULL) 
    { 
        free( pp1 ); 
    } 
    if ( pp2 != NULL ) 
    { 
        free( pp2 ); 
    } 
  
    returnnRet; 

  
用下面程序来测试一下排1百万个随机整数的花费时间: 
voidTest_MQuickSort (void) 

    UINTi; 
    UINTuCount = 1000000; //1000个 
  
    srand(time(NULL)); 
    void **pp = (void **)malloc(uCount * sizeof(void *)); 
    for ( i = 0; i < uCount; i++ ) 
    { 
        pp[i] = (void *)(rand() % uCount); 
    } 
  
       clock_tt1 = clock(); 
    INTnRet = MQuickSort(pp, 0, uCount-1, UIntCompare); 
       clock_tt2 = clock(); 
  
       printf("MQuickSort 1000000 Time %ld\n", t2-t1); 
  
    free(pp); 

  
在双核CPU上运行后,打印出花费的时间为 281 ms 比单任务版的快速排序函数快了188ms左右,效率提高了 188/281 = 67% 左右。 
在单核CPU上运行上面的Test_MQuickSort函数,花费的时间约为532ms. 
  
可见双核CPU中,多任务程序速度还是有很大提高的。 
  
当然上面的多任务版的快速排序程序还有很大的改进余地,当对4个区间排好序后,后面的归并操作都是在一个任务里运行的,对整体效率会产生影响。估计将程序继续优化后,速度还能再快一些。

其中的一个网友评论给大家参考
以下是引用片段:
不是任务切换费时间,而是代码中本身有一部分是单任务执行的。  
另外改写成多任务后,比单任务版的排序在单核机上的总时间本身要多
电脑硬件热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号