Witam.
Ostatnio napisałem sobie prostą sieć neuronową w języku autohotkey, z racji, że jest to język interpretacyjny (ala Python) to napisem także bibliotekę dll w c++ dla najbardziej wymagających funkcji co w sposób znaczny poprawiło wydajność. Teraz chciałem iść krok dalej i robić obliczenia w wielu wątkach czego nigdy wcześniej nie robiłem. Po przeczytaniu kilku poradników i modyfikacji jednego z przykładów w internecie finalnie udało mi się uzyskać pożądany efekt jednak wydajność zamiast wzrosnąć to jeszcze spadła o ponad połowę.
Moje pytani więc brzmi, co mogę zrobić aby poprawić wydajność albo co robię źle?
tutaj jest moja pierwotna funkcja do mnożenia macierzy
double matrix_dot_ahk3(AHKObject *a, AHKObject *b,AHKObject *c)
{
int rowsA = a->Count;
int colsA = a->A->Value.ahkObject->Count;
int rowsB = b->Count;
int colsB = b->A->Value.ahkObject->Count;
int colsC = colsB;
for(int rowA=0;rowA<rowsA;rowA++){
for(int colB=0;colB<colsB;colB++){
for(int colA=0;colA<colsA;colA++){
c->A[rowA].Value.ahkObject->A[colB].Value.d += ahk_readMatrix(a,rowA,colA)*ahk_readMatrix(b,colA,colB);
}
}
}
return 1;
}
Teraz to samo z tą różnicą, że nie jest liczona całość na raz tylko określoną ilość rzędów z macierzy A przypisuję poszczególnym wątkom, tzn jeśli macierz A ma 400 rzędów to na każdy wątek przypada 100 innych rzędów dla 4 wątków.
double matrix_dot_ahk(AHKObject *a, AHKObject *b,AHKObject *c)
{
int rowsA = a->Count;
int step = ceil_(rowsA,MAX_THREAD); // ilość rzędów macierzy A na wątek
void *pp[MAX_THREAD];
thread_dot_param args[MAX_THREAD];
for (int i = 0; i < MAX_THREAD; i++){
pp[i] = (void*)&args[i];
}
for (int i = 0; i < MAX_THREAD; i++) {
int from = step*i;
int to = from+step;
to = to>rowsA ? rowsA : to;
args[i].from = from;
args[i].to = to;
args[i].a = a;
args[i].b = b;
args[i].c = c;
// cout << from << " " << to << endl;
if(to>=rowsA)
break;
}
threads_call(MAX_THREAD,multi,pp);
return 666;
}
void* multi(void* arg)
{
thread_dot_param *pp = (thread_dot_param*)arg;
int from = pp->from;
int to = pp->to;
if(from==to){
pthread_exit(NULL);
return NULL;
}
AHKObject *a = pp->a;
AHKObject *b = pp->b;
AHKObject *c = pp->c;
int rowsA = a->Count;
int colsA = a->A->Value.ahkObject->Count;
int rowsB = b->Count;
int colsB = b->A->Value.ahkObject->Count;
int colsC = colsB;
for(int rowA=from;rowA<to;rowA++){
for(int colB=0;colB<colsB;colB++){
for(int colA=0;colA<colsA;colA++){
c->A[rowA].Value.ahkObject->A[colB].Value.d += ahk_readMatrix(a,rowA,colA)*ahk_readMatrix(b,colA,colB);
}}}
pthread_exit(NULL);
return NULL;
}
void threads_call(int threadsN,void*(*funkcja)(void*),void** args){
// declaring four threads
pthread_t threads[threadsN];
// Creating four threads, each evaluating its own part
for (int i = 0; i < threadsN; i++) {
pthread_create(&threads[i], NULL, funkcja,args[i]);
}
// joining and waiting for all threads to complete
for (int i = 0; i < threadsN; i++){
pthread_join(threads[i], NULL);
}
}