モンテカルロアルゴリズムを実行する簡単なプログラムがあります。アルゴリズムを使用した 1 回の反復には副作用がないため、複数のスレッドで実行できるはずです。したがって、これは私のプログラム全体の関連部分であり、C++11 で記述されています。
void task(unsigned int max_iter, std::vector<unsigned int> *results, std::vector<unsigned int>::iterator iterator) {
for (unsigned int n = 0; n < max_iter; ++n) {
nume::Album album(535);
unsigned int steps = album.fill_up();
*iterator = steps;
++iterator;
}
}
void aufgabe2() {
std::cout << "\nAufgabe 2\n";
unsigned int max_iter = 10000;
unsigned int thread_count = 4;
std::vector<std::thread> threads(thread_count);
std::vector<unsigned int> results(max_iter);
std::cout << "Computing with " << thread_count << " threads" << std::endl;
int i = 0;
for (std::thread &thread: threads) {
std::vector<unsigned int>::iterator start = results.begin() + max_iter/thread_count * i;
thread = std::thread(task, max_iter/thread_count, &results, start);
i++;
}
for (std::thread &thread: threads) {
thread.join();
}
std::ofstream out;
out.open("out-2a.csv");
for (unsigned int count: results) {
out << count << std::endl;
}
out.close();
std::cout << "Siehe Plot" << std::endl;
}
不可解なことは、追加するスレッドが増えるほど遅くなることです。4 つのスレッドを使用すると、次のようになります。
real 0m5.691s
user 0m3.784s
sys 0m10.844s
一方、単一のスレッドの場合:
real 0m1.145s
user 0m0.816s
sys 0m0.320s
CPU コア間でデータを移動するとオーバーヘッドが増える可能性があることvector
は認識していますが、起動時に宣言する必要があり、途中で変更しないでください。複数のコアでこれが遅くなる特定の理由はありますか?
私のシステムは i5-2550M で、4 つのコア (2 + ハイパースレッディング) があり、g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3 を使用しています。
アップデート
スレッドを使用しない (1) と、多くのユーザー負荷がかかりますが、スレッドを使用すると (2)、ユーザー負荷よりも多くのカーネルが発生することがわかりました。
10,000 回の実行:
http://wstaw.org/m/2013/05/08/stats3.png
100K 実行:
http://wstaw.org/m/2013/05/08/Auswahl_001.png
100K 実行すると、次の結果が得られます。
スレッドがまったくありません:
real 0m28.705s
user 0m28.468s
sys 0m0.112s
プログラムの各部分のスレッド。これらの部分は同じメモリを使用することさえないため、同じコンテナーの同時実行も同様に実行する必要があります。しかし、もっと時間がかかります:
real 2m50.609s
user 2m45.664s
sys 4m35.772s
そのため、3 つの主要部分で CPU の 300% を使用していますが、6 倍の時間がかかります。
1Mランで、real 4m45
やるのに時間がかかりました。real 20m
私は以前に 1M を実行しましたが、少なくともreal 30m
.