Linux上で実行されているC++プログラムがあり、メインスレッドとは関係なく計算コストの高い作業を行うために新しいスレッドが作成されています(計算作業は結果をファイルに書き込むことで完了し、最終的には非常に大きくなります)。ただし、パフォーマンスが比較的低下しています。
プログラムを(他のスレッドを導入せずに)簡単に実装すると、約2時間でタスクが完了します。マルチスレッドプログラムでは、同じタスクを実行するのに約12時間かかります(これは、生成された1つのスレッドのみでテストされました)。
スレッドを単一のCPUに設定するためのpthread_setaffinity_np (使用しているサーバーで使用可能な24個のうち)や、スケジューリングポリシーを設定するためのpthread_setschedparam(SCHED_BATCHのみを試した)など、いくつか試しました。 )。しかし、これらの影響はこれまで無視できる程度でした。
この種の問題の一般的な原因はありますか?
編集:私が使用しているいくつかのサンプルコードを追加しました。これは、うまくいけば最も関連性の高い部分です。関数process_job()は実際に計算作業を行うものですが、ここに含めるには多すぎます。基本的に、2つのデータファイルを読み込み、これらを使用してインメモリグラフデータベースでクエリを実行します。このデータベースでは、結果が2つの大きなファイルに数時間にわたって書き込まれます。
編集パート2:明確にするために、問題は、私が持っているアルゴリズムのパフォーマンスを向上させるためにスレッドを使用したいということではありません。むしろ、アルゴリズムの多くのインスタンスを同時に実行したいと思います。したがって、マルチスレッドをまったく使用しなかった場合と同じように、スレッドに入れたときにアルゴリズムが実行されると思います。
編集パート3:すべての提案をありがとう。一部の人が示唆しているように、私は現在いくつかのユニットテストを行っています(どの部分が遅くなっているのかを確認しています)。プログラムの読み込みと実行に時間がかかるため、テストの結果を確認するのに時間がかかります。そのため、応答が遅れたことをお詫び申し上げます。私が明らかにしたかった主なポイントは、スレッド化によってプログラムの実行が遅くなる可能性がある理由の可能性があると思います。私がコメントから集めたものから、それは単にそうであるべきではありません。妥当な解決策が見つかったら投稿します。ありがとうございます。
(最終)編集パート4:結局のところ、問題はスレッド化に関連していないことがわかりました。この時点で説明するのは面倒ですが(コンパイラー最適化レベルの使用を含む)、ここに投稿されたアイデアは非常に役に立ち、高く評価されました。
struct sched_param sched_param = {
sched_get_priority_min(SCHED_BATCH)
};
int set_thread_to_core(const long tid, const int &core_id) {
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(core_id, &mask);
return pthread_setaffinity_np(tid, sizeof(mask), &mask);
}
void *worker_thread(void *arg) {
job_data *temp = (job_data *)arg; // get the information for the task passed in
...
long tid = pthread_self();
int set_thread = set_thread_to_core(tid, slot_id); // assume slot_id is 1 (it is in the test case I run)
sched_get_priority_min(SCHED_BATCH);
pthread_setschedparam(tid, SCHED_BATCH, &sched_param);
int success = process_job(...); // this is where all the work actually happens
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
...
pthread_t temp;
pthread_create(&temp, NULL, worker_thread, (void *) &jobs[i]); // jobs is a vector of a class type containing information for the task
...
return 0;
}