この質問は、私が以前に尋ねたのと同じプログラムに関するものです。要約すると、次のようなループ構造を持つプログラムがあります。
for (int i1 = 0; i1 < N; i1++)
for (int i2 = 0; i2 < N; i2++)
for (int i3 = 0; i3 < N; i3++)
for (int i4 = 0; i4 < N; i4++)
histogram[bin_index(i1, i2, i3, i4)] += 1;
bin_index
この質問の目的のために、共有状態を使用または変更しない、その引数の完全に決定論的な関数です。つまり、明らかに再入可能です。
私は最初、単一のスレッドを使用するためにこのプログラムを書きました。n
次に、スレッドが外側のループのすべての反復を実行するように、複数のスレッドを使用するように変換しましたi1 % nthreads == n
。したがって、各スレッドで実行される関数は次のようになります
for (int i1 = n; i1 < N; i1 += nthreads)
for (int i2 = 0; i2 < N; i2++)
for (int i3 = 0; i3 < N; i3++)
for (int i4 = 0; i4 < N; i4++)
thread_local_histogram[bin_index(i1, i2, i3, i4)] += 1;
すべてのthread_local_histogram
s は、最後にメインスレッドで合計されます。
奇妙なことに、ある特定のサイズの計算に対して 1 つのスレッドだけでプログラムを実行すると、約 6 秒かかります。2 つまたは 3 つのスレッドで実行し、まったく同じ計算を行うと、約 9 秒かかります。何故ですか?デュアルコア CPU を使用しているため、2 つのスレッドを使用する方が 1 つのスレッドよりも高速であると予想されます。プログラムはミューテックスやその他の同期プリミティブを使用しないため、2 つのスレッドを並行して実行できるはずです。
time
参考までに: 1 つのスレッドの典型的な出力(これは Linux 上にあります):
real 0m5.968s
user 0m5.856s
sys 0m0.064s
および 2 つのスレッド:
real 0m9.128s
user 0m10.129s
sys 0m6.576s
コードはhttp://static.ellipsix.net/ext-tmp/distintegral.ccsにあります。
PS まさにこの種のもののために設計されたライブラリがあり、おそらくパフォーマンスが向上する可能性があることは知っていますが、それが私の最後の質問でしたので、それらの提案をもう一度聞く必要はありません。(さらに、pthreads を学習体験として使用したかったのです。)