c - Shared Data in pthread Programming -
there's i'm still not sure in pthread programming. , i'll appreciate if can tell me absolute answer.
my previous question here: how assign array variable in simple pthread programming?
and now, i'm working on matrix multiplication. works using this:
typedef struct { int rowidx; int (*mata)[size], (*matb)[size], (*matc)[size]; } newtype; int main (){ int matriksa[size][size]; int matriksb[size][size]; int matriksc[size][size]; (i=0;i<num_thread;i++) { (*block).rowidx = i; (*block).mata = matriksa; (*block).matb = matriksb; (*block).matc = matriksc; pthread_create(&arrthread[i], null, matrixmul, (void *)block); block++; } } void *matrixmul(void *x){ newtype *p = (newtype *) x; int = (*p).rowidx; int j,k; (j=0;j<size;j++){ int result = 0; for(k=0;k<size;k++){ int maik = (*p).mata[i][k]; int mbkj = (*p).matb[k][j]; result = result + (maik*mbkj); } (*p).matc[i][j] = result; } pthread_exit(null); }
the matrixmul doing matrix multiplication matc = mata x matb.
i tried using struct before didn't work.
typedef struct { int rowidx; int **mata, **matb, **matc; } newtype;
apparently i've read, variable array can considered pointer holds address of first element in array. 2-dimensional array, must tell compiler size of column. must use (*mata)[size] instead of **mata in typedef struct.
but i'm still not sure doing there. did copy 2d-array 2d-array assigning pointer or what? kinda confusing....lol...
my next questions regarding these lines:
(*block).mata = matriksa; (*block).matb = matriksb; (*block).matc = matriksc;
what happened there? each block variable in code above has own copy of matrix data? or share having pointer refer same location in memory means mata, matb, , matc behave static variable (as in object oriented programming)? in other words, there 1 copy of mata, matb, , matc; , threads access shared data simultantly? or there many copies of 'mata's, , each of them has own different allocation in ram?
same question first post, happened behind these lines? (*z).arra = arraya; (*z).arrb = arrayb; (*z).arrc = arrayc;
are codes above efficient enough task (array addition , matrix multiplication)? or there way more efficient memory-allocation point of view?
@code-guru: there i've posted new question.
the basic problem in threaded programming make sure there no possibility of 2 separate threads trying modify data @ same time, or read data thread might modifying. (if there no danger data might modified, ok 2 threads read same non-changing data @ same time.)
applied matrix multiplication problem, threads going read matrix , matrix b, don't have control access variables — assuming initialized before launch threads.
on other hand, result matrix c, being accessed write, either have sure have partitioned workload no 2 threads ever access same elements (they working on disjoint subsets of matrix c), or have coordinate access 1 thread modifying given cell @ given time, , you've enforced mutual exclusion (a mutex
) or equivalent.
your questions
you've not shown how block
defined, amongst other things. helpful if show sscce (short, self-contained, correct example), 1 show below. saves having reverse-engineer code fragment working code. done properly, not take space. (an earlier edition of answer went off on tangent because code not complete!)
in original, created num_thread
threads process size
x size
matrices. since didn't show definition of size
or num_thread
, have assume 2 sizes equal. various different recipes disaster available depending on relative sizes of 2 constants.
the threads being given same matrices work on, asking about. each thread has pointer same memory.
assuming
(*z).arra = arraya;
refer(*block).arra = matriksa;
assignment, you're assigning pointer array of size integersblock->arra
(which equivalent(*block).arra
). that's little contorted, legitimate. you'll need careful using that.you ask if code efficient enough. first sub-question: produce correct answer (and guaranteed)? i'm not yet sure that. however, if each thread working on 1 column of result matrix, should safe enough.
sscce
this code uses c99 constructs. won't compile under c89.
#include <stdio.h> #include <pthread.h> enum { size = 3 }; typedef struct { int rowidx; int (*mata)[size]; int (*matb)[size]; int (*matc)[size]; } newtype; extern void *matrixmul(void *); static void print_matrix(const char *tag, int d1, int d2, int matrix[d1][d2]) { printf("%s: (%d x %d)\n", tag, d1, d2); (int = 0; < d1; i++) { printf("%d:", i); (int j = 0; j < d2; j++) printf(" %6d", matrix[i][j]); putchar('\n'); } } int main(void) { int matriksa[size][size] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; int matriksb[size][size] = { { 11, 12, 13 }, { 14, 15, 16 }, { 17, 18, 19 } }; int matriksc[size][size]; newtype thedata[size]; newtype *block = thedata; pthread_t arrthread[size]; (int = 0; < size; i++) { block->rowidx = i; block->mata = matriksa; block->matb = matriksb; block->matc = matriksc; //matrixmul(block); pthread_create(&arrthread[i], null, matrixmul, block); block++; } (int = 0; < size; i++) pthread_join(arrthread[i], 0); print_matrix("matrix a", size, size, matriksa); print_matrix("matrix b", size, size, matriksb); print_matrix("matrix c", size, size, matriksc); } void *matrixmul(void *x){ newtype *p = (newtype *) x; int = p->rowidx; (int j = 0; j < size; j++) { int result = 0; for(int k = 0; k < size; k++) { int maik = p->mata[i][k]; int mbkj = p->matb[k][j]; result += maik * mbkj; } p->matc[i][j] = result; } //pthread_exit(null); return(0); }
you might note i've added matrix printing function (and used it). added sample data pair of 3x3 matrices, , i've verified answer correct. did testing in 2 steps:
- check single-threaded version of code produced correct answer.
- add threading.
if step 1 produced wrong answer, know you've got basic calculations fix; isn't thread-induced problem (because there 1 thread!). fortunately, produces right answer. adding threading simple.
output
$ ./ta matrix a: (3 x 3) 0: 1 2 3 1: 4 5 6 2: 7 8 9 matrix b: (3 x 3) 0: 11 12 13 1: 14 15 16 2: 17 18 19 matrix c: (3 x 3) 0: 90 96 102 1: 216 231 246 2: 342 366 390 $
Comments
Post a Comment