前提・実現したいこと
C言語でpthreadsライブラリを用いたプログラムを作成する課題を行っています。
1からN = 100000までの整数の合計を求めて出力する下記のプログラムを並列化するというものです。
元の並列化されていないプログラムが下記の通りです。
c
1#include <stdio.h> 2#include <stdlib.h> 3 4#define N 100000 5 6int count(int start, int end); 7 8int main(void){ 9 int sum = 0; 10 11 sum = count(1, N); 12 printf("sum of 1..%d = %d\n", N, sum); 13 exit(0); 14} 15 16int count(int start, int end){ 17 int i; 18 int sum = 0; 19 20 for (i = start ; i <=end ; i++){ 21 sum += i; 22 } 23 return sum; 24}
計算が正しいと下記のような表示をすることになっています。
c
1$ ./a.out 2sum of 1..100000 = 705082704
並列化したが、うまく動作しないプログラム
ここではスレッドを4つに分けて、1番目は125000、2番目は2500150000、、、としてそれぞれの総和を求め、4つの総和を最後に求め出力するプログラムです。4つ以外でも対応するように、スレッドの本数をMとして、1番目のスレッドは1~N/M, 2番目はN/M+1~2N/M,、、、というように合計を担当する区間を分割することが条件です。
構造体の変数は、startがスレッドの計算する始めの番号、endが計算する終わりの番号、sumが総和の計算結果です。
関数countが計算を行うスレッドです。
c
1#include <stdio.h> 2#include <stdlib.h> 3#include <pthread.h> 4 5#define N 100000 6#define M 4 7 8struct arg_t { 9 int start; 10 int end; 11 int sum; 12}; 13 14// startからendまでの整数を合計して返す 15void *count(void *arg){ 16 int i; 17 struct arg_t *a = (struct arg_t *)arg; 18 19 for (i = a->start ; i <= a->end ; i++){ 20 a->sum += i; 21 } 22 return NULL; 23} 24 25int main(void){ 26 int sum = 0; 27 int i; 28 pthread_t thr[M]; 29 struct arg_t arg[M]; 30 int a = N/M; 31 32 for (i = 0 ; i < M ; i++){ 33 arg[i].start = (i * a) + 1; 34 arg[i].end = (i + 1) * a; 35 pthread_create(&thr[i], NULL, count, (void *)&arg[i]); 36 } 37 38 for (i = 0 ; i < M ; i++){ 39 pthread_join(thr[i], NULL); 40 } 41 sum += arg[i].sum; 42 printf("sum of 1..%d = %d\n", N, sum); 43 exit(0); 44} 45
いまいちpthread_join,pthread_createの意味と挿入のタイミングが分かりません。実行を何度か行っても毎回結果はばらばらで、マイナスになってしまう場合もあり、その理由もわかりません。
並列化に苦手意識があるので、勉強しなおすために投稿させていただきました。よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/07/10 08:04