多线程采用相同的时间作为单线程快速排序

时间:2012-06-25 09:54:52

标签: c++ multithreading performance pthreads

我正在开发linux,但多线程和单线程都需要340毫秒。有人能告诉我我正在做的事情有什么问题吗?

这是我的代码

#include<time.h>
#include<fstream>
#define SIZE_OF_ARRAY 1000000
using namespace std;

struct parameter
{
        int *data;
        int left;
        int right;
};
void readData(int *data)
{
        fstream iFile("Data.txt");
        for(int i = 0; i < SIZE_OF_ARRAY; i++)
                iFile>>data[i];
}

int threadCount = 4;

int Partition(int *data, int left, int right)
{
        int i = left, j = right, temp;
        int pivot = data[(left + right) / 2];
        while(i <= j)
        {
                while(data[i] < pivot)
                        i++;
                while(data[j] > pivot)
                        j--;
                if(i <= j)
                {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                        i++;
                        j--;
                }
        }
        return i;
}

void QuickSort(int *data, int left, int right)
{
        int index = Partition(data, left, right);
        if(left < index - 1)
                QuickSort(data, left, index - 1);
        if(index < right)
                QuickSort(data, index + 1, right);
}

//Multi threading code starts from here
void *Sort(void *param)
{
        parameter *param1 = (parameter *)param;
        QuickSort(param1->data, param1->left, param1->right);
        pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
        clock_t start, diff;
        int *data = new int[SIZE_OF_ARRAY];
        pthread_t threadID, threadID1;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
        pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
        parameter param, param1;
        readData(data);
        start = clock();
        int index = Partition(data, 0, SIZE_OF_ARRAY - 1);
        if(0 < index - 1)
        {
                param.data = data;
                param.left = 0;
                param.right = index - 1;
                pthread_create(&threadID, NULL, Sort, (void *)&param);
        }
        if(index < SIZE_OF_ARRAY - 1)
        {
                param1.data = data;
                param1.left = index + 1;
                param1.right = SIZE_OF_ARRAY;
                pthread_create(&threadID1, NULL, Sort, (void *)&param1);
        }
        pthread_attr_destroy(&attr);
        pthread_join(threadID, NULL);
        pthread_join(threadID1, NULL);
        diff = clock() - start;
        cout<<"Sorting Time = "<<diff * 1000 / CLOCKS_PER_SEC<<"\n";
        delete []data;
        return 0;
}
//Multithreading Ends here

Single thread main function
int main(int argc, char *argv[])
{
        clock_t start, diff;
        int *data = new int[SIZE_OF_ARRAY];
        readData(data);
        start = clock();
        QuickSort(data, 0, SIZE_OF_ARRAY - 1);
        diff = clock() - start;
        cout<<"Sorting Time = "<<diff * 1000 / CLOCKS_PER_SEC<<"\n";
        delete []data;
        return 0;
}
//Single thread code ends here
some of functions single thread and multi thread use same

3 个答案:

答案 0 :(得分:2)

clock返回总CPU时间,而不是停机时间。

如果你有2个CPU和2个线程,那么在同时运行两个线程clock之后,将返回2秒的CPU时间(每个线程的CPU时间总和)。

所以结果完全可以预料到。无论你有多少CPU,所有CPU的总运行时间总和都是一样的。

答案 1 :(得分:1)

请注意,您从主线程中调用一次分区...

代码在同一个内存块上工作,当另一个访问同一个内存块时,它会阻止CPU工作。除非您的数据非常大,否则很可能会有很多此类点击。

最后,如果您的算法在使用一个线程运行时以内存速度运行,则添加更多线程无济于事。我曾经用图像数据做过这样的测试,并且有多个线程降低了总速度,因为这个过程非常耗费内存以至于两个线程都在努力访问内存......结果比没有线程更糟糕。 / p>

今天真正快速的计算机真的很快就是在每台计算机上运行一个非常密集的进程,而不是在一台计算机上运行大量的线程(或进程)。

答案 2 :(得分:1)

使用生产者 - 消费者队列构建一个线程池,其中有24个线程挂起。将数据分成两部分并向池发出mergesort任务对象,mergesort对象应该向队列发出更多的mergesorts对,并等待信号完成,依此类推,直到mergersort对象发现它有[L1缓存 - 大小数据]。然后,该对象将其数据进行排序,并将完成信号发送给其父任务。

如果在24核上没有变得非常快,我将停止发布线程..

..它将并行处理多种排序。

..并且该池可用于其他任务。

..并且没有没有性能破坏,死锁生成join(),synchronize(),(如果你除了PC队列,它只锁定足够长的时间来推送对象引用),没有线程 - 创建开销,没有狡猾的线程停止/终止/破坏代码。像理发师一样,没有等待 - 一旦线程完成任务就可以获得另一个任务。

没有线程微管理,没有调整,(你现在可以创建64个线程,为下一代盒子做好准备)。你可以使线程数可调 - 只需在运行时添加更多线程,或者通过排队毒丸来删除一些线程。

根本不需要对线程的引用 - 只需设置'em off,(将队列作为参数传递)。