2013-03-16 9 views
5

各スレッドが1回の乗算を行い、次にメインスレッドがすべての結果を合計して適切な場所に配置するスレッドを使用して行列乗算を行いたいのですが(他のスレッドが終了した後の)最終的な行列の中に現れます。マトリクススレッドでの乗算

私がしようとしているのは、各スレッドの結果を保持する単一の行配列を作成することです。次に、配列を調べ、結果を最終行列に追加します。

例:

A = [{1,4}、{2,5}、{3,6}] B = [{8,7,6}、{:あなたが行列を有する場合5,8,3}]

[8,20,7,16,12,16など] を配列にしたい場合は、2つの数字を足し合わせて配列をループします私の最終的な配列。

これはHWの割り当てなので、正確なコードは探していませんが、結果を配列に正しく保存する方法についてはいくつかの論理があります。私はどの行列をどのように扱っているのかを把握するのに苦労しています。

ありがとうございました。

EDIT2:1回の乗算ごとに1つのスレッドが必要であることを忘れてしまいました。上記の例では、それぞれ独自の計算を行うスレッドが18個あります。

編集:私は現在、このコードをベースとして使用しています。

#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); 
} 

出典:あなたが派遣する必要があるだろうと私はまた、あなたがそれらを拾うために後で結合を使用するかどうかわからないサンザシ多くのスレッドhttp://macboypro.wordpress.com/2009/05/20/matrix-multiplication-in-c-using-pthreads-on-linux/

+1

これは、およそ10万回前に行われています。マシン上のCPUコア数 'C'を求め、必要なRow x Columnベクトル乗算の数を決定し、後者を前者(大まかに)で分けて' Cスレッドは互いに独立して処理される。任意のモジュロ( 'C-1'までの余分なベクトル)が、第1の一連のスレッドに余分な乗算として送られる。より効率的でシンプルなアルゴリズムを得ることは難しいでしょう。特に、ロックがまったく必要ないことは絶対に考えてください。 – WhozCraig

+0

申し訳ありませんが、わかりませんでした。割当てによれば、実行されなければならない1回の乗算ごとに1つのスレッドが存在しなければならない。意味するところに、私が与えた行列の例では、18の乗算を行う18のスレッドがあります。 効率的なものではありません。それは単なるHWの運動です。 – Kinru

+0

ええ、私はちょうど運動でなければならないと仮定します。あなたが 'A [500] [800] x B [800] [1000]'のようなものを取ると、そのコンセプトはかなり早く劣化します。それが大きくなればなるほど、あなたは乗算をちょうど作り出すことができるときにスレッドに参加するのに費やす時間が増えます。まぁ。がんばろう! – WhozCraig

答えて

0

わかりません。

私は、各スレッドがでその行データをピックアップすることを推測してい
#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; 

:私は..私は、処理する行を追跡する方法として、スレッドIDを使用するので、あなたはここにCにあるようなものを推測しています定義された型fooを持つポインタ*行整数や浮動小数点数、または複雑な型の束。あなたがスレッドに渡す必要があるものは何でも。

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

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

は、その後、あなたのメインのコードセグメントでのようなもの:しかし

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

:後に続いて

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); 
} 

thread_parm_t *parm=NULL; 

は、次にようなものでスレッドを派遣します実際の仕事は必要行データを受け取ったthr_rowcrunch(void * parm)で行われ、次に各スレッドは自身のスレッド番号を知っています。あなたがそのディスパッチされたスレッドでやっていることの勇気は、しかし私はただ推測することができます。

ここで助けようとしていますが、これがはっきりしているかどうかはわかりません。

+0

行列乗算の実際の入力データを共有できますか?私は実際には自分の理由だけでこの問題に興味があります。私は、きちんとスレッド化されたソリューションを試してみたいと思います。コーヒーとコードのソリューションを提供するには完全に価値のある方法です。 –

+0

実際の入力データは可変です。代入のために、行列を読み込んで結果を出力するためにファイルI/Oを行う必要があります。本当に私の質問には関係ありません。コードは行列に依存しているべきではないので、私はオリジナルのポストで与えた例を使ってこれを試してみようとしています。 – Kinru