いくつかの強力な行列処理を実行しようとしているコードがいくつかあるので、マルチスレッド化すると高速になると思いました。ただし、私の意図は、スレッドを存続させて、将来さらに多くの処理に使用できるようにすることです。ここに問題があります。コードのマルチスレッド バージョンは、シングル スレッドよりも遅く実行されます。問題は、スレッドにシグナルを送る/維持する方法にあると思います。
Windows と C++ で pthread を使用しています。スレッドのコードは次のとおりです。 runtest()は、行列の計算が行われる関数です。
void* playQueue(void* arg)
{
while(true)
{
pthread_mutex_lock(&queueLock);
if(testQueue.empty())
break;
else
testQueue.pop();
pthread_mutex_unlock(&queueLock);
runtest();
}
pthread_exit(NULL);
}
playQueue ()関数は pthread に渡される関数であり、現在私が持っているのは、1000 個のアイテムのキュー (testQueue) があり、100 個のスレッドがあるということです。各スレッドは、キューが空になるまで実行され続けます (したがって、ミューテックス内のもの)。
マルチスレッドの実行が非常に遅い理由は、偽共有と呼ばれるもの (だと思いますか?) と、スレッドにruntest()を呼び出すように通知し、スレッドを存続させる方法が貧弱であるためだと思います。
マルチスレッドバージョンが反復バージョンよりも高速に (または少なくとも同等の速度で) 実行されるようにするには、これを行う効果的な方法は何でしょうか?
これが私のコードのフルバージョンです(マトリックスのものを除く)
# include <cstdlib>
# include <iostream>
# include <cmath>
# include <complex>
# include <string>
# include <pthread.h>
# include <queue>
using namespace std;
# include "matrix_exponential.hpp"
# include "test_matrix_exponential.hpp"
# include "c8lib.hpp"
# include "r8lib.hpp"
# define NUM_THREADS 3
int main ( );
int counter;
queue<int> testQueue;
queue<int> anotherQueue;
void *playQueue(void* arg);
void runtest();
void matrix_exponential_test01 ( );
void matrix_exponential_test02 ( );
pthread_mutex_t anotherLock;
pthread_mutex_t queueLock;
pthread_cond_t queue_cv;
int main ()
{
counter = 0;
/* for (int i=0;i<1; i++)
for(int j=0; j<1000; j++)
{
runtest();
cout << counter << endl;
}*/
pthread_t threads[NUM_THREADS];
pthread_mutex_init(&queueLock, NULL);
pthread_mutex_init(&anotherLock, NULL);
pthread_cond_init (&queue_cv, NULL);
for(int z=0; z<1000; z++)
{
testQueue.push(1);
}
for( int i=0; i < NUM_THREADS; i++ )
{
pthread_create(&threads[i], NULL, playQueue, (void*)NULL);
}
while(anotherQueue.size()<NUM_THREADS)
{
}
cout << counter;
pthread_mutex_destroy(&queueLock);
pthread_cond_destroy(&queue_cv);
pthread_cancel(NULL);
cout << counter;
return 0;
}
void* playQueue(void* arg)
{
while(true)
{
cout<<counter<<endl;
pthread_mutex_lock(&queueLock);
if(testQueue.empty()){
pthread_mutex_unlock(&queueLock);
break;
}
else
testQueue.pop();
pthread_mutex_unlock(&queueLock);
runtest();
}
pthread_mutex_lock(&anotherLock);
anotherQueue.push(1);
pthread_mutex_unlock(&anotherLock);
pthread_exit(NULL);
}
void runtest()
{
counter++;
matrix_exponential_test01 ( );
matrix_exponential_test02 ( );
}
したがって、ここの「matrix_exponential_tests」は許可を得てこの Web サイトから取得したもので、すべての行列計算が行われる場所です。カウンタは、デバッグしてすべてのインスタンスが実行されていることを確認するためにのみ使用されます。