0

そこで、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 の 2 乗を意味します。
これが私がタスクを分割する方法です。画面の幅と高さを意味しますx_length。 画面を幅ごとに n 分割し、範囲をスレッドに送信して計算します。y_length

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);
}
4

2 に答える 2

1

clock()pthreadを使用すると、経過時間
clock()測定に使用できないため、正しく動作することがわかり
ました。gettimeofday(timeval, NULL)

于 2013-04-22T10:26:47.913 に答える
0

clock()はい、 Pthreadsに問題があります。オプションを使用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;
于 2013-04-23T14:11:32.000 に答える