2

擬似コード:

void * thread_start(void *arg) {
    while (1) {
        /* for each column. Only run columns the thread_num
           is assigned to */
        column_count = thread_num;
        for (; column_count < dim - 1; column_count+=threads) {
             /* do thread work for data chunk */
        }

        /* barrier */
        barrier_result = pthread_barrier_wait(barrier);

        if (not_finished == 0) {
            /* finished */
            break;
            /* break while loop, end thread.
               The barrier is now broken because it is no longer
               getting called by this thread */
        }

        /* we are not finished, loop around and 
           do thread work on next data chunk */
    }
}

バリアに関する私の問題は、他のスレッドの前に終了するスレッドをどのように処理するかです。

バリアとは、すべてのスレッドが他のすべてのスレッドを待たなければならないことを意味します。

すべてのスレッドが同時に終了することを保証するための手法は何ですか?

ループを続けようとしましたが、「スレッド作業」を無視しましたが、この場合、8 つのスレッドすべてが終了し、スレッドに「すべて完了しました。今すぐ終了できます」と伝える賢明な方法はありません。

編集:

アルゴリズム:

  1. データのセグメントに対して操作を実行する
  2. スレッドのデータのセグメントが終了した場合は終了します。
  3. バリア待ち。
  4. 1 つのスレッドがデータの一部を新しいデータに置き換えます
  5. 1を繰り返します。

編集2:

バリアを 1 サイズ小さいバリアで上書きするエレガントな方法はありますか? (バリアの周りにミューテックスを配置せずに)

4

1 に答える 1

0

プログラムロジックの性質上、スレッドが同時に終了するようにします。スレッドが異なる時間に終了するようにアルゴリズムが呼び出す場合、バリアはその具体的なアルゴリズムに適した同時実行制御メカニズムではありません。

編集:

「finished_count」をアトミックにインクリメントしてループし、バリアに参加する以外は何の作業も行わず、その数がバリア カウントよりも小さい場合 (適切なミューテックスを使用して finished_count への読み取り/書き込みを保護します)。

編集: 追加された説明をよく理解しているかどうかわかりません。元のコードに基づいてこれを書いただけです。おそらくうまくいくでしょう:

int finished_count;

void * thread_start(void *arg) {
    int finished = 0;

    while (1) {

        if (finished) {
            pthread_mutex_lock (&finished_lock);
            if (finished_count == 8) {
                pthread_mutex_unlock (&finished_lock);
                break;
            }
            pthread_mutex_unlock (&finished_lock);
        } else {
            /* for each column. Only run columns the thread_num
               is assigned to */
            column_count = thread_num;
            for (; column_count < dim - 1; column_count+=threads) {
                /* do thread work for data chunk */
            }

            /* set "finished" as appropriate */

            /* Check if we have just finished.  */
            if (finished) {
                pthread_mutex_lock (&finished_lock);
                ++finished_count;
                pthread_mutex_unlock (&finished_lock);
            }
        }

        barrier_result = pthread_barrier_wait(barrier);
    }

    return 0;
}

編集:

コピーまたは再初期化に関する上記の私のコメントを明確にするために、POSIX は次のように述べています。

http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_init.html

初期化済みのバリアを指定して pthread_barrier_init() が呼び出された場合、結果は未定義です。

同期の実行に使用できるのは、バリアによって参照されるオブジェクトのみです。pthread_barrier_destroy() または pthread_barrier_wait() の呼び出しでそのオブジェクトのコピーを参照した結果は未定義です。

于 2011-11-24T22:07:33.067 に答える