同时使用多个线程c ++

时间:2018-05-01 03:09:35

标签: c++ multithreading visual-studio-2015

我在makelbrot程序中使用多个线程时遇到问题。

我厌倦了教程之后的一种方式

    int sliceSize = 800 / threads;
    double start = 0, end = 0;
    for (int i = 0; i < threads; i++)
    {
        start = i * sliceSize;
        end = ((1 + i) * sliceSize);

        thrd.push_back(thread(compute_mandelbrot, left, right, top, bottom, start, end));

    }

    for (int i = 0; i < threads; i++)
    {
        thrd[i].join();
    }
    thrd.clear();

但代码只需要一半的时间来计算,同时使用8个线程。

我也尝试了一些更复杂的东西,但它根本不起作用

void slicer(double left, double right, double top, double bottom)
{
    /*promise<int> prom;
    future<int> fut = prom.get_future();*/


    int test = -1;
    double start = 0, end = 0;
    const size_t nthreads = std::thread::hardware_concurrency(); //detect how many threads cpu has
    {
        int sliceSize = 800 / nthreads;

        std::cout << "CPU has " << nthreads << " threads" << std::endl;
        std::vector<std::thread> threads(nthreads);

        for (int t = 0; t < nthreads; t++)
        {

            threads[t] = std::thread(std::bind(
                [&]()
            {

                mutex2.lock();
                test++;

                start = (test) * sliceSize;
                end = ((test + 1) * sliceSize);

                mutex2.unlock();

                compute_mandelbrot(left, right, top, bottom, start, end);


            }));
        }
        std::for_each(threads.begin(), threads.end(), [](std::thread& x) {x.join(); }); //join threads
    }
}
但是看起来,即使在使用互斥锁后,它一下子计算了8个东西,但它并没有更快。

这让我在过去7小时内头疼,我想自杀。救命。

1 个答案:

答案 0 :(得分:1)

当您尝试通过多线程加速工作量时,有很多在游戏中,并且在完美的世界中,在倍增时获得Nx加速几乎是不可能的由N个线程组成。有些事情需要牢记:

  1. 如果您正在使用超线程(因此在系统上每个虚拟核心使用1个线程,而不仅仅是每个物理核心),那么您将无法获得2个真实核心的等效性能 - 您&# 39;得到一些百分比(可能大约1.2倍左右)。
  2. 操作系统(Windows)将在您的工作负载执行时执行操作。当这些操作系统任务切入您的应用时间时,它是相当随机的,但它会产生影响。总是希望你的CPU时间有一部分会被Windows窃取。
  3. 任何类型的同步都会严重影响性能。在你的第二个例子中,互斥量非常大,可能会影响性能。
  4. 内存访问,缓存访问等将会发挥作用。多个线程访问所有地方的内存将导致缓存压力,这将产生(潜在)影响。
  5. 我很好奇 - 你在这看什么样的时间?你在每个线程上传递了多少次迭代?为了深入了解时间顺序,您可以尝试使用queryPerformanceCounter记录每个线程的开始/结束时间,以查看每个线程的运行时间,启动时间等。在此处发布时间1,2,4和8个线程可能会略微发光。

    希望这至少有点帮助...