以前に「アクティブなスレッドをプールするクラスを作ってみた。」と題してエントリーを書いたが、そのときの作ったクラスをWindows上で動作確認した。特に修正する必要なくビルドできたが、動作確認をしていた時におかしな挙動に気がついてしまった。複数のスレッドを用意しても、実は1スレッドしか動いていない様なのである。
というわけで、中をよく見てみると、キューから関数を取得した後に関数終了までロック解除を行っていないようなのである。
- ロックをかける
- 関数をキューからポップ
- 関数を実行
- ロックを解除
となっていたので、関数の実行が終わるまでロックされたままになるのは当然で、マルチスレッドの意味があまりない作りとなっていた。
そこで、その部分を修正した。→dthreadpool.zipをダウンロード
ついでにスレッド数を変化させたときの実行時間の変化を取得してみた。
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "dthreadpool.hpp"
using namespace std;
using namespace boost;
void writeMsg(string str){
int b = 0;
double dd = 0.0;
for (int i = 0; i < 100; i++){
int a = 0;
double d = 0.0;
//cout << str << ": " << i << ": " << ctime(&clock);
for(int j = 0; j < 5000; j++){
for(int k = 0; k < 5000; k++){
a += j * k;
d += i / 3 + j / 7;
}
}
b+=a;
dd += d;
ofstream out("tmp\\" + str, ios::app);
out << b << dd << endl;
out.close();
}
}
int main(int argc, char* argv[])
{
int nThread = atoi(argv[1]);
DECS::DThreadPool thd;
thd.addThread(nThread);
vector thName;
char buffer[BUFSIZ];
for(int i = 0; i < 500; i++){
string strTmp = "No" + (string)(itoa(i, buffer, 10)) + ".txt";
thName.push_back(strTmp);
}
time_t clock;
time(&clock);
time_t tStart = clock;
for(int i = 0; i < 100; i++){
thd.request(boost::bind(writeMsg, thName.at(i)));
}
thd.close();
time(&clock);
time_t tEnd = clock;
ofstream out(argv[2], std::ios::app);
out << nThread << "," << tEnd - tStart << endl;
out.close();
return EXIT_SUCCESS;
}
こんな感じのメイン関数を作成し、複数スレッドをforループを回して、実行時間を秒単位で計測した。時間の計測単位が秒なので、あまり精密とはいえないが、それなりに差は見られるだろうと予想して行った。
スレッド数を1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16,20, 24, 32, 64, 128と変化させて実行した結果は次のグラフのようになった。

スレッド数が16までの部分でグラフを作成すると次のようになる。

今回実行したマシンはCore i 7 2670QMで4Core 8Threadだが、この結果からわかるように、物理コア数を超えてスレッドを用意しても、それほどパフォーマンス向上しないということと、今回の例ではあまりハイパースレッディング機能は役立っていないということがわかる。
もう少し、メモリやディスクとのI/O待ちが各スレッドで動いている関数内でランダムに発生すると、スレッド数8ぐらいまでは性能の向上が見られるかもしれない。また、動かすマシンのスペックによって最適なスレッド数は変わるので、スレッド数の設定をコード内に埋め込んでしまうのは、やはりあり得ない選択だと実感した。。