Множество Мандельброта не будет ускоряться с использованием pthread

Итак, я пишу программу для вычисления множества Мандельброта с использованием pthread.
Это функция потока:

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 означает вычисление следующей итерации Мандельброта.

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.
Результат набора Мандельброта правильный, однако время вычисления всегда одинаково, несмотря на то, что я увеличил количество потоков с 1 до 8.
Потому что "enter" были распечатаны одновременно за секунду до pthread_join , я считаю, что потоки выполнялись параллельно.
Я предполагаю, что проблема может заключаться в том, что в partial_compute есть функция защиты от потоков, но я не могу ее найти. (Я попытался представить комплексное число как float вместо класса)
Есть ли здесь какая-то ошибка? Спасибо за помощь.

Обновление:
Извините за неполную информацию.
z.length() означает квадрат комплексного числа z.
Вот как я разделил задачу. x_length и y_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);
}

person Wei-Tsung    schedule 22.04.2013    source источник
comment
Какой процессор (сколько ядер)? Что делает z.length()?   -  person Mats Petersson    schedule 22.04.2013
comment
Можете ли вы показать нам, как вы разделяете набор для вычислений между потоками, то есть какой поток вычисляет какую часть общего набора?   -  person ogni42    schedule 22.04.2013
comment
Поместите код, который также запускает потоки...   -  person UmNyobe    schedule 22.04.2013
comment
Возможно, код ограничен скоростью доступа к памяти, а не скоростью ваших вычислений?   -  person Bo Persson    schedule 22.04.2013
comment
Хорошо, теперь количество потоков, которые вы запускаете? Количество ядер у вас есть на этой машине? Как долго выполняется расчет?   -  person Mat    schedule 22.04.2013
comment
Самое простое объяснение состоит в том, что ваша функция clock() просто не имеет достаточного разрешения, чтобы показать разницу.   -  person Hans Passant    schedule 22.04.2013


Ответы (2)


Я обнаружил, что проблема заключается в clock()......
clock() нельзя использовать для измерения прошедшего времени при использовании pthread,
поэтому я обнаружил, что gettimeofday(timeval, NULL) может работать правильно.

person Wei-Tsung    schedule 22.04.2013

Да, есть проблема с clock() в Pthreads. Вы можете использовать clock_gettime() с опцией CLOCK_MONOTONIC, чтобы правильно измерить время в Pthreads. Для этого вам также потребуется связать расширения POSIX Realtime (-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;
person Community    schedule 23.04.2013