Mandelbrot set不会使用pthread加速

时间:2013-04-22 08:44:26

标签: c++ pthreads mandelbrot

所以,我正在编写一个使用pthread计算Mandelbrot集的程序。
这是线程功能:

void *partial_compute(void *arg) {
    cout << "enter" << flush;
    Range *range = (Range*)arg;
    Comp z, c;
    for (int i = range->begin; i <= range->end; i++) {
        for (int j = 0; j < y_length; j++) {
            z.set(0.0, 0.0);
            c.set(x_start + (x_end - x_start) * i / x_length, y_start + (y_end - y_start) * j / y_length);
            int k;
            for (k = 0; k < 256; k++) {
                z = z.next(c);
                if (z.length() >= 4.0) {
                    break;
                }
            }
            *(canvas + i * y_length + j) = k;
        }
    }
    pthread_exit(NULL);
}


哪个Comp是一个复数类,z.next表示计算下一个Mandelbrot迭代。

Comp Comp::next(Comp c) {
    Comp n(next_real(c), next_imag(c));
    return n;
}
float Comp::next_real(Comp c) {
    return _real * _real - _imag * _imag + c.real();
}
float Comp::next_imag(Comp c) {
    return 2 * _real * _imag + c.imag();
}

我在clock_t之前和pthread_create之后设置了一对pthread_join
Mandelbrot设置的结果是正确的,但是,尽管我将线程数从1增加到8,但计算时间始终相同。
由于"enter"pthread_join之前的同一时间打印出来,我相信线程是并行执行的。
我想问题可能是partial_compute中存在线程安全函数,但我找不到它。 (我试图用float而不是类来表示复数) 我在这里犯了什么错误吗?谢谢你的帮助。

更新:
对不起,信息不完整。
z.length()表示复数z的平方。
这是我分割任务的方式。 x_lengthy_length表示屏幕的宽度和高度。
我将屏幕分成n个宽度,然后将范围发送到线程进行计算。

int partial_length = x_length / num_threads;
for (int i = 0; i < num_threads; i++) {
    range[i].begin = i * partial_length;
    range[i].end = range[i].begin + partial_length - 1;
    pthread_create(&threads[i], NULL, partial_compute, (void *)&range[i]);
}
// wait all the threads finished
for (int i = 0; i < num_threads; i++) {
    pthread_join(threads[i], NULL);
}

2 个答案:

答案 0 :(得分:1)

我发现问题是clock() ......
clock()不能用于衡量使用pthread时的经过时间,
因此我发现gettimeofday(timeval, NULL)可以正常工作。

答案 1 :(得分:0)

是的,Pthreads中的clock()存在问题。您可以clock_gettime()使用CLOCK_MONOTONIC选项,在Pthreads中正确测量时间。您还需要链接POSIX实时扩展(-lrt)。

以下是一个例子:

struct timespec begin, end;
double elapsed;

clock_gettime(CLOCK_MONOTONIC, &begin);

// spawn threads to do work here

clock_gettime(CLOCK_MONOTONIC, &end);

elapsed = end.tv_sec - begin.tv_sec;
elapsed += (end.tv_nsec - begin.tv_nsec) / 1000000000.0;
相关问题