使用多线程在c ++中生成mandelbrot图像。没有加速?

时间:2014-01-25 18:58:54

标签: c++ multithreading mandelbrot

所以我之前发布了一个类似的问题,但我没有发布足够的代码来获得我需要的帮助。即使我现在回去并添加了该代码,我也不认为它会被注意到,因为这个问题很老并且“已经回答”了。所以这是我的问题:

我正在尝试生成一个mandelbrot分形的一部分。我可以很好地生成它,但是当我添加更多内核时,无论问题大小有多大,额外的线程都不会产生加速。我对多线程是全新的,它可能只是我想念的小东西。无论如何,这里是产生分形的函数:

void mandelbrot_all(std::vector<std::vector<int>>& pixels, int X, int Y, int numThreads) {
    using namespace std;

    vector<thread> threads (numThreads);
    int rowsPerThread = Y/numThreads;
    mutex m;

    for(int i=0; i<numThreads; i++) {
        threads[i] = thread ([&](){
            vector<int> row;
            for(int j=(i-1)*rowsPerThread; j<i*rowsPerThread; j++) {
                row = mandelbrot_row(j, X, Y);
                {
                    lock_guard<mutex> lock(m);
                    pixels[j] = row;
                }
            }
        });
    }
    for(int i=0; i<numThreads; i++) {
        threads[i].join();
    }
}

std::vector<int> mandelbrot_row(int rowNum, int topX, int topY) {
    std::vector<int> row (topX);
    for(int i=0; i<topX; i++) {
        row[i] = mandelbrotOne(i, rowNum, topX, topY);
    }
    return row;
}

int mandelbrotOne(int currX, int currY, int X, int Y) { //code adapted from http://en.wikipedia.org/wiki/Mandelbrot_set
    double x0 = convert(X, currX, true);
    double y0 = convert(Y, currY, false);
    double x = 0.0;
    double y = 0.0;
    double xtemp;
    int iteration = 0;
    int max_iteration = 255;
    while ( x*x + y*y < 2*2  &&  iteration < max_iteration) {
        xtemp = x*x - y*y + x0;
        y = 2*x*y + y0;
        x = xtemp;
        ++iteration;
    }
    return iteration;
}

mandelbrot_all传递一个向量来保存像素,向量的最大X和Y,以及要使用的线程数,这是在程序运行时从命令行获取的。它试图在多个线程之间逐行拆分工作。不幸的是,似乎即使这就是它正在做的事情,它也不会让它变得更快。如果您需要更多详细信息,请随时提出,我会尽力提供。

提前感谢您的帮助。

编辑:预先保留的向量 编辑2:在四核笔记本电脑上运行此代码,问题大小为9600x7200。一个线程(超过5次运行)平均花费36590000个周期,四个线程平均花费55142000个周期。

1 个答案:

答案 0 :(得分:2)

代码中的问题是所有线程都捕获并访问相同的i变量。这会产生竞争条件,结果非常不正确。

您需要将它作为参数传递给线程lambda,并且还要更正范围(i-1将使您的索引超出范围)。