Intel PentiumデュアルコアプロセッサT2370(Acer Extensa)を搭載したノートパソコンでは、単純なマルチスレッドスピードアップテストを実行しました。私はLinuxを使用しています。コードは下に貼り付けられます。私は2〜3倍のスピードアップを期待していましたが、私は減速を2倍に驚かせました。gccの最適化レベル-O0 ... -O3でも同じことを試みましたが、毎回同じ結果が得られました。私はpthreadsを使用しています。私はまた、(コード内の3つのスレッドの代わりに)2つのスレッドで同じことを試みましたが、パフォーマンスは似ていました。マルチスレッドのマイナススピードプログラム
何故その理由が考えられますか?より速いバージョンは約20秒という比較的長い時間がかかったので、起動時のオーバーヘッドの問題ではないようです。
注:このコードはバグが多いです(シリアルとパラレルバージョンの出力が異なるため実際にはあまり意味がありません)。その意図は、同じ数の命令に対する高速化の比較を「取得」することであった。
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
class Thread{
private:
pthread_t thread;
static void *thread_func(void *d){((Thread *)d)->run();}
public:
Thread(){}
virtual ~Thread(){}
virtual void run(){}
int start(){return pthread_create(&thread, NULL, Thread::thread_func, (void*)this);}
int wait(){return pthread_join(thread, NULL);}
};
#include <iostream>
const int ARR_SIZE = 100000000;
const int N = 20;
int arr[ARR_SIZE];
int main(void)
{
class Thread_a:public Thread{
public:
Thread_a(int* a): arr_(a) {}
void run()
{
for(int n = 0; n<N; n++)
for(int i=0; i<ARR_SIZE/3; i++){ arr_[i] += arr_[i-1];}
}
private:
int* arr_;
};
class Thread_b:public Thread{
public:
Thread_b(int* a): arr_(a) {}
void run()
{
for(int n = 0; n<N; n++)
for(int i=ARR_SIZE/3; i<2*ARR_SIZE/3; i++){ arr_[i] += arr_[i-1];}
}
private:
int* arr_;
};
class Thread_c:public Thread{
public:
Thread_c(int* a): arr_(a) {}
void run()
{
for(int n = 0; n<N; n++)
for(int i=2*ARR_SIZE/3; i<ARR_SIZE; i++){ arr_[i] += arr_[i-1];}
}
private:
int* arr_;
};
{
Thread *a=new Thread_a(arr);
Thread *b=new Thread_b(arr);
Thread *c=new Thread_c(arr);
clock_t start = clock();
if (a->start() != 0) {
return 1;
}
if (b->start() != 0) {
return 1;
}
if (c->start() != 0) {
return 1;
}
if (a->wait() != 0) {
return 1;
}
if (b->wait() != 0) {
return 1;
}
if (c->wait() != 0) {
return 1;
}
clock_t end = clock();
double duration = (double)(end - start)/CLOCKS_PER_SEC;
std::cout << duration << "seconds\n";
delete a;
delete b;
}
{
clock_t start = clock();
for(int n = 0; n<N; n++)
for(int i=0; i<ARR_SIZE; i++){ arr[i] += arr[i-1];}
clock_t end = clock();
double duration = (double)(end - start)/CLOCKS_PER_SEC;
std::cout << "serial: " << duration << "seconds\n";
}
return 0;
}
も参照してください:アプリケーションがIO-バインドする必要がありますので、あなたのスレッドはありませんWhat can make a program run slower when using more threads?
あなたはこれをどうアーキテクチャ上で実行されていますか?いくつのCPUコアが関与していますか?キャッシュレイアウトとは何ですか? (これらはマルチスレッドコードのパフォーマンスに影響を与えるすべての要因ですので、可能な限り多くの関連情報を提供してください) – Marcin
私はOSも大きな違いをもたらすと思います。 Linuxのスケジューラは、他のほとんどのものと比べて非常に高速です。 – rmeador
最適化されたバージョンはSSEを使用していますか? – tstenner