代码之家  ›  专栏  ›  技术社区  ›  user6214135

同时使用多个线程c++

  •  2
  • user6214135  · 技术社区  · 7 年前

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

    我厌倦了学习教程

        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 回复  |  直到 7 年前
        1
  •  2
  •   Varrak    7 年前

    当您试图通过多线程加速工作负载时,会有很多问题需要解决,而在完美的世界中,当乘以N个线程时,几乎不可能得到Nx的加速。要记住一些事情:

    1. 如果您使用的是超线程(因此在系统上每个虚拟核使用1个线程,而不仅仅是每个物理核),那么您将无法获得与2个真实核同等的性能-您将获得一定的百分比(可能是1.2倍左右)。
    2. 当您的工作负载正在执行时,操作系统(Windows)将执行一些操作。这些操作系统任务会在什么时候、什么时候占用你的应用程序时间,这是相当随机的,但这会有所不同。总是希望你的CPU时间有一定比例会被windows偷走。
    3. 任何类型的同步都会严重影响性能。在第二个示例中,互斥量相当大,可能会影响性能。
    4. 内存访问、缓存访问等都将发挥作用。多个线程到处访问内存将对缓存造成压力,这将产生(潜在)影响。

    我很好奇,你现在的处境是怎样的?您在每个线程上传递了多少次迭代?要深入了解并查看在计时方面发生的情况,您可以尝试使用queryPerformanceCounter记录每个线程的开始/结束时间,以查看每个线程的运行时间、开始时间等。在此处发布1、2、4和8个线程的时间可能会有所帮助。

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