使用多个线程时程序较慢

Mar*_*ing 5 c++ multithreading c++11

我有一个简单的程序,可以执行一些蒙特卡罗算法.使用algorithmn的一次迭代没有副作用,因此我应该能够使用多个线程运行它.所以这是我整个程序的相关部分,用C++ 11编写:

void task(unsigned int max_iter, std::vector<unsigned int> *results, std::vector<unsigned int>::iterator iterator) {
    for (unsigned int n = 0; n < max_iter; ++n) {
        nume::Album album(535);
        unsigned int steps = album.fill_up();
        *iterator = steps;
        ++iterator;
    }
}

void aufgabe2() {
    std::cout << "\nAufgabe 2\n";

    unsigned int max_iter = 10000;

    unsigned int thread_count = 4;

    std::vector<std::thread> threads(thread_count);
    std::vector<unsigned int> results(max_iter);

    std::cout << "Computing with " << thread_count << " threads" << std::endl;

    int i = 0;
    for (std::thread &thread: threads) {
        std::vector<unsigned int>::iterator start = results.begin() + max_iter/thread_count * i;
        thread = std::thread(task, max_iter/thread_count, &results, start);
        i++;
    }

    for (std::thread &thread: threads) {
        thread.join();
    }

    std::ofstream out;
    out.open("out-2a.csv");
    for (unsigned int count: results) {
        out << count << std::endl;
    }
    out.close();

    std::cout << "Siehe Plot" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

令人费解的是,我添加的线程越多,速度越慢.有4个线程,我得到这个:

real    0m5.691s
user    0m3.784s
sys     0m10.844s
Run Code Online (Sandbox Code Playgroud)

而使用单个线程:

real    0m1.145s
user    0m0.816s
sys     0m0.320s
Run Code Online (Sandbox Code Playgroud)

我意识到在CPU内核之间移动数据可能会增加开销,但是vector应该在启动时声明,而不是在中间修改.在多核上,这有什么特别的原因要慢吗?

我的系统是i5-2550M,它有4个内核(2 +超线程),我使用g ++(Ubuntu/Linaro 4.7.3-1ubuntu1)4.7.3

更新

我看到没有使用线程(1),它会有很多用户负载,而使用线程(2),它将拥有比用户负载更多的内核:

10K运行:

http://wstaw.org/m/2013/05/08/stats3.png

100K运行:

http://wstaw.org/m/2013/05/08/Auswahl_001.png

当前 main.cpp

运行100K后,我得到以下结果:

完全没有线程:

real    0m28.705s
user    0m28.468s
sys     0m0.112s
Run Code Online (Sandbox Code Playgroud)

程序的每个部分的线程.这些部分甚至不使用相同的内存,所以同一个容器的并发性也应该是.但它需要更长的时间:

real    2m50.609s
user    2m45.664s
sys     4m35.772s
Run Code Online (Sandbox Code Playgroud)

因此,尽管三个主要部分占用了我的CPU的300%,但它们需要6倍的时间.

通过1M运行,它需要real 4m45做.我以前跑了1M,至少花了它real 20m,甚至不行real 30m.

Yur*_*ula 5

在GitHub评估您当前的main.cpp.除了上面提供的评论:

  1. 是的,rand()不是线程安全的,所以在运行多线程业务逻辑之前,有可能需要用随机值预先填充一些数组(这样可以减少可能的锁定量).如果您计划进行一些堆活动(在多线程之前进行预分配或使用自定义每线程分配器),那么内存分配也是如此.
  2. 不要忘记其他过程.如果计划在4个内核上使用4个线程,则意味着您将与其他软件(至少是OS例程)竞争CPU资源.
  3. 文件输出是一个很大的更衣室玩家.你在每次循环迭代时做"<<"运算符并且它花了你很多(我记得我过去的一个有趣的案例:间接地修复一个多线程错误的日志输出.因为通用记录器是锁驱动的,它是某种同步原语,请注意!).
  4. 最后,没有任何类型的保证,多线程应用程序可能比单线程更快.有一堆特定于CPU,特定于环境的方面.