#include<stdlib.h>
#include<string.h>
#include<windows.h>
//#include<assert.h> // thread-unsafe
/***
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
***/
#define _CRITICIAL_SECTION 0
typedef struct _MATRIX
{
int **array;
int col,row;
}MATRIX,Matrix,*pMatrix;
typedef struct _PARAM
{
MATRIX M1,M2,R;
int n;
}PARAM,Param,*ptrParam;
int sample1[] = {
3,4,2,0,4,7,3,0,9,1,2,8,7,4,9,1,
7,3,8,2,3,1,0,4,5,8,7,3,5,6,8,2,
};
int sample2[] = {
7,3,8,2,3,1,0,4,5,8,7,3,5,6,8,2,
3,4,2,0,4,7,3,0,9,1,2,8,7,4,9,1,
};
int n_thread;
#if _CRITICIAL_SECTION
CRITICAL_SECTION cs;
#endif
void assert(bool a){ if(a!=true) {printf("alert!!\n"); exit(0);}/*return ;*/}
void init_matrix(Matrix *, int, int);
int** create_array(int, int);
void set_zero(Matrix *M);
void free_array(int **, int, int);
void mul_matrix(Matrix *, Matrix *, Matrix *);
void mul_matrix_thread(Matrix *, Matrix *, Matrix *);
void cal_part(Matrix *, Matrix *, Matrix *, int);
DWORD WINAPI cal_part_thread(void* arg);
void set_sample(Matrix *, int *);
void print_matrix(Matrix);
int main(int argc, char *argv[])
{
Matrix M1,M2,Result;
init_matrix(&M1, 4, 3 );
init_matrix(&M2, 3, 4 );
set_sample(&M1, sample1);
set_sample(&M2, sample2);
print_matrix(M1);
print_matrix(M2);
n_thread = M1.col;
mul_matrix_thread(&M1,&M2,&Result);
print_matrix(Result);
free_array(M1.array, M1.row, M1.col);
free_array(M2.array, M2.row, M2.col);
free_array(Result.array, Result.row, Result.col);
return 0;
}
void init_matrix(Matrix *M,int w,int h)
{
M->col = h;
M->row = w;
M->array = create_array(w,h);
set_zero(M);
}
int** create_array(int w, int h)
{
int height=h,width=w;
int **array = (int **) malloc( sizeof(int *)* height);
array[0] = (int *) malloc( sizeof(int) * width*height );
int i;
for( i=1 ; i< height ; i++)
array[i] = array[ i-1 ] + width;
return array;
}
void set_zero(Matrix *M)
{
memset(M->array[0], 0x00, sizeof(int)*M->col*M->row);
}
void free_array(int **array, int w, int h)
{
assert(array!=NULL);
assert(array[0]!=NULL);
free(array[0]);
free(array);
}
void mul_matrix(Matrix *M1, Matrix *M2, Matrix *R)
{
assert(M1->row == M2->col);
assert(M1->col == M2->row);
init_matrix(R,M1->col,M2->row);
int n;
for( n=0; n < R->col ; n++ ){
cal_part(M1,M2,R,n);
}
}
void mul_matrix_thread(Matrix *M1, Matrix *M2, Matrix *R)
{
PARAM *param=NULL;
param = (PARAM*)malloc(sizeof(PARAM)*n_thread);
HANDLE *hThread=NULL;
hThread = (HANDLE*)malloc(sizeof(HANDLE)*n_thread);
#if _CRITICIAL_SECTION
InitializeCriticalSection(&cs);
#endif
assert(M1->row == M2->col);
assert(M1->col == M2->row);
init_matrix(R,M1->col,M2->row);
int i;
for( i=0; i< n_thread; i++){
param[i].M1 = *M1;
param[i].M2 = *M2;
param[i].R = *R;
param[i].n = i;
}
int n;
for( n=0; n < R->col ; n++ ){
hThread[n] = CreateThread(NULL,0,cal_part_thread,(void*)(param+n),0,NULL);
if(hThread[n]>0){
printf("hThread[%d] created\n",n);
}
else{
printf("hThread[%d] fail to create\n",n);
}
}
WaitForMultipleObjects(n_thread,hThread,TRUE,INFINITE);
#if _CRITICIAL_SECTION
DeleteCriticalSection(&cs);
#endif
for( n=0; n < R->col ; n++){
CloseHandle(hThread[n]);
}
printf("\n");
}
void cal_part(Matrix *M1, Matrix *M2, Matrix *R, int n)
{
assert(M1->row == M2->col);
assert(M1->col == M2->row);
assert(M1->col == R->row);
assert(M2->row == R->col);
int buf;
int i,j;
for( i=0 ; i < R->row; i++ ){
for( j=0,buf=0 ; j < M1->row ; j++ ){
buf += M1->array[n][j]*M2->array[j][i];
}
R->array[n][i] = buf;
}
}
DWORD WINAPI cal_part_thread(void* arg)
{
PARAM param = *(PARAM *)arg;
cal_part(¶m.M1,¶m.M2,¶m.R,param.n);
}
void set_sample(Matrix *M, int *src)
{
assert(M->array!=NULL);
int i,j;
for( i=0; i < M->col; i++){
for( j=0; j < M->row; j++){
M->array[i][j] = src[i*M->row + j];
}
}
}
void print_matrix(Matrix M)
{
int i,j;
for( i=0; i < M.col; i++){
for( j=0; j < M.row; j++){
printf("%3d ",M.array[i][j]);
}
printf("\n");
}
printf("\n");
}
'c/c++' 카테고리의 다른 글
Console API 모음 (MSDN) (0) | 2011.07.14 |
---|---|
Console API를 이용하여 더블버퍼링 (0) | 2011.07.14 |
c/c++ 2차원(이차원) 배열 동적할당 방법2 (0) | 2010.08.06 |
c언어 2차원(이차원) 배열 동적 할당 방법 (0) | 2010.08.03 |
math.h 의 sqrt()를 사용하지 않고 제곱근 구하기 (0) | 2010.08.03 |