ネタ元 → マルチスレッドの出番?
ふつーのアプリでもマルチスレッドが役に立ちそうな例。
たとえばソート。
ソート対象の配列を前半と後半に分け、それぞれをスレッドにソートしてもらって、
ソート完了後両者をマージします。
配列の前半/後半はまったく独立してますから、それぞれのスレッドは他方の
ことなどお構い無しにフルスロットルでぶん回れます。
やってみましょ。
#include <algorithm>
#include <utility>
#include <cstdlib>
#include <process.h>
#include <windows.h>
unsigned __stdcall process(void* pvParam) {
std::pair* range = (std::pair*)pvParam;
std::sort(range->first, range->second);
return 0;
}
int main() {
const int N = 200000;
const int N2 = N*2;
int *data = new int[N2];
// 地味に単スレッド
{
srand(1);
for ( int i = 0; i < N2; ++i ) data[i] = std::rand();
// data[0..N2] をソート
std::cout << "single thread ..." << std::flush;
long t = GetTickCount();
std::sort(data, data+N2);
std::cout << GetTickCount() - t << std::endl;
}
// 派手に複スレッド
{
srand(1);
for ( int i = 0; i < N2; ++i ) data[i] = std::rand();
std::pair firstHalf(data,data+N);
std::pair secondHalf(data+N,data+N2);
DWORD thID;
HANDLE hThreads[2];
std::cout << "dual threads ..." << std::flush;
long t = GetTickCount();
// data[0..N]とdata[N..N2] を並行してソート
hThreads[0] = (HANDLE)_beginthreadex(0, 0, &process, &firstHalf, 0, (unsigned*)&thID);
hThreads[1] = (HANDLE)_beginthreadex(0, 0, &process, &secondHalf, 0, (unsigned*)&thID);
WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);
// 前半と後半をマージ
std::inplace_merge(data, data+N, data+N2);
std::cout << GetTickCount() - t << std::endl;
CloseHandle( hThreads[0] );
CloseHandle( hThreads[1] );
}
delete[] data;
}
結果:
single thread ...109
dual threads ...62
ぱちぱちぱちー♪
# シングル・コア機でやっても遅くなるだけでしょけどね。