2013-03-16 24 views
5

Ich bin auf der Suche nach einer Matrix multiplizieren mit Threads wo jeder Thread eine einzige Multiplikation und dann der Haupt-Thread summiert alle Ergebnisse und fügt sie in die entsprechenden Spot in der letzten Matrix (nachdem die anderen Threads beendet wurden).Matrix Multiplizieren mit Threads (jeder Thread does single multiplizieren)

Die Art, wie ich es versuche, ist ein einzelnes Zeilenarray zu erstellen, das die Ergebnisse jedes Threads enthält. Dann würde ich durch das Array gehen und + die Ergebnisse in die endgültige Matrix einfügen.

Ex: Wenn Sie die Matrizen:

A = [{1,4}, {2,5}, {3,6}] B = [{8,7,6}, { 5,4,3}]

Dann möchte ich ein Array halten [8, 20, 7, 16, 6, 12, 16 usw.] Ich würde dann durch das Array durchschleifen summieren alle 2 Zahlen und platzieren sie in mein letztes Array.

Dies ist eine HW-Zuweisung, also suche ich nicht nach genauem Code, sondern nach einer Logik, wie die Ergebnisse im Array richtig gespeichert werden. Ich habe Probleme damit zu wissen, wo ich in jeder Matrix bin, damit ich keine Zahlen verpasse.

Danke.

EDIT2: Vergessen zu erwähnen, dass es für jede einzelne zu erstellende Multiplikation einen einzelnen Thread geben muss. Für das obige Beispiel bedeutet dies, dass es 18 Threads geben wird, von denen jeder seine eigene Berechnung durchführt.

EDIT: Ich verwende derzeit diesen Code als Basis, um von zu arbeiten.

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define M 3 
#define K 2 
#define N 3 
#define NUM_THREADS 10 

int A [M][K] = { {1,4}, {2,5}, {3,6} }; 
int B [K][N] = { {8,7,6}, {5,4,3} }; 
int C [M][N]; 

struct v { 
    int i; /* row */ 
    int j; /* column */ 
}; 

void *runner(void *param); /* the thread */ 

int main(int argc, char *argv[]) { 

    int i,j, count = 0; 
    for(i = 0; i < M; i++) { 
     for(j = 0; j < N; j++) { 
     //Assign a row and column for each thread 
     struct v *data = (struct v *) malloc(sizeof(struct v)); 
     data->i = i; 
     data->j = j; 
     /* Now create the thread passing it data as a parameter */ 
     pthread_t tid;  //Thread ID 
     pthread_attr_t attr; //Set of thread attributes 
     //Get the default attributes 
     pthread_attr_init(&attr); 
     //Create the thread 
     pthread_create(&tid,&attr,runner,data); 
     //Make sure the parent waits for all thread to complete 
     pthread_join(tid, NULL); 
     count++; 
     } 
    } 

    //Print out the resulting matrix 
    for(i = 0; i < M; i++) { 
     for(j = 0; j < N; j++) { 
     printf("%d ", C[i][j]); 
     } 
     printf("\n"); 
    } 
} 

//The thread will begin control in this function 
void *runner(void *param) { 
    struct v *data = param; // the structure that holds our data 
    int n, sum = 0; //the counter and sum 

    //Row multiplied by column 
    for(n = 0; n< K; n++){ 
     sum += A[data->i][n] * B[n][data->j]; 
    } 
    //assign the sum to its coordinate 
    C[data->i][data->j] = sum; 

    //Exit the thread 
    pthread_exit(0); 
} 

Quelle: http://macboypro.wordpress.com/2009/05/20/matrix-multiplication-in-c-using-pthreads-on-linux/

+1

Dies wurde etwa hunderttausend Mal zuvor getan.Sie werden * viel * besser ausgeschaltet, wenn Sie die CPU-Kernzählung 'C' auf der Maschine bestimmen, indem Sie bestimmen, wie viele Vektormultiplikationen der Reihe x Spalte benötigt werden, indem Sie letztere durch (grob) teilen und an 'senden C'-Fäden werden unabhängig voneinander verarbeitet. Jeder Modulo (zusätzliche Vektoren bis zu "C-1") werden als zusätzliche Multiplikationen an die erste Reihe von Threads gesendet. Sie werden sich schwer tun, einen effizienteren und einfacheren Algorithmus zu bekommen, insbesondere wenn man bedenkt, dass überhaupt keine Verriegelung erforderlich ist. – WhozCraig

+0

Sorry, mir war nicht klar. Je nach Aufgabe muss für jede einzelne Multiplikation 1 Thread vorhanden sein. Bedeutung, für die Beispielmatrizen, die ich gab, wird es 18 Threads geben, die 18 Multiplikationen machen. Es soll nicht effizient sein. Es ist nur eine HW-Übung. – Kinru

+0

Ja, ich nehme an, es muss nur eine Übung sein. Das Konzept verschlechtert sich ziemlich schnell, wenn Sie etwas wie "A [500] [800] x B [800] [1000]" nehmen. Je größer es wird, desto mehr Zeit verbringst du damit, Threads zu beginnen, wenn du nur Multiplikationen erstellen kannst. Ah, gut. Viel Glück! – WhozCraig

Antwort

0

Nicht sicher haw viele Threads Sie benötigen würde schicken, und ich bin auch nicht sicher, ob Sie später verwenden würde kommen, um sie abzuholen. Ich vermute, Sie sind in C hier, damit ich die Thread-ID als eine Möglichkeit wäre .. etwas zu verarbeiten, welche Zeile zu verfolgen wie:

#define NUM_THREADS 64 
/* 
* struct to pass parameters to a dispatched thread 
*/ 
typedef struct { 
    int value;  /* thread number */ 
    char somechar[128]; /* char data passed to thread */ 
    unsigned long ret; 
    struct foo *row; 
} thread_parm_t; 

Wo ich vermute, dass jeder Thread seine Zeilendaten abholen in der Zeiger * Zeile, die einen definierten Typ foo hat. Ein Haufen Integer oder Floats oder sogar komplexe Typen. Was auch immer Sie brauchen, um an den Thread zu gelangen.

/* 
* the thread to actually crunch the row data 
*/ 
void *thr_rowcrunch(void *parm); 

pthread_t tid[NUM_THREADS]; /* POSIX array of thread IDs */ 

Dann in Ihrem Haupt-Codesegment so etwas wie:

thread_parm_t *parm=NULL; 

versenden Sie dann die Fäden mit so etwas wie:

for (i = 0; i < NUM_THREADS; i++) { 
    parm = malloc(sizeof(thread_parm_t)); 
    parm->value = i; 
    strcpy(parm->somechar, char_data_to-pass); 
    fill_in_row (parm->row, my_row_data); 
    pthread_create(&tid[i], NULL, thr_insert, (void *)parm); 
} 

Dann später:

for (i = 0; i < NUM_THREADS; i++) 
    pthread_join(tid[i], NULL); 

jedoch die echte Arbeit braucht t o in thr_rowcrunch (void * parm) getan werden, die die Zeilendaten erhält und dann jeder Thread nur kennt seine eigene Thread-Nummer. Die Eingeweide dessen, was Sie in diesem gesendeten Thread tun, kann ich nur erraten.

Nur versuchen, hier zu helfen, nicht sicher, ob das klar ist.

+0

Können Sie Ihre tatsächlichen Eingabedaten für die Matrix multiplizieren? Ich bin eigentlich an diesem Problem interessiert, auch wenn es nur aus meinen eigenen Gründen ist. Ich würde gerne eine saubere Lösung erarbeiten, eine lohnenswerte Möglichkeit, einen Kaffee zu trinken und eine Lösung zu programmieren. –

+0

Die tatsächlichen Eingangsdaten sind variabel. Für die Zuweisung müssen wir einige Datei-E/A durchführen, um die Matrizen einzulesen und dann das Ergebnis auszugeben. Nicht wirklich relevant für meine Frage. Da der Code in Abhängigkeit von den Matrizen keine Rolle spielt, habe ich das Beispiel verwendet, das ich in meinem ursprünglichen Beitrag gegeben habe, um zu versuchen, dies zum Laufen zu bringen. – Kinru

Verwandte Themen