質問編集履歴

2

曖昧な表現を修正

2023/11/01 11:54

投稿

daiwa
daiwa

スコア0

test CHANGED
File without changes
test CHANGED
@@ -97,7 +97,8 @@
97
97
  }
98
98
  ```
99
99
  SIZE×SIZEのある規則に則って生成された行列A、Bに対してC=ABを求めるコードです。このコードはベースとなるもので、SIZEに定義する数字以外は手を加えません。このコードをpthread.hを用いて並列化する課題です。~~元のコードをベースに自分で書いたものが以下です。~~
100
+
100
- gdbの結果受けさらに修正したものを下に載せます。
101
+ gdbの結果受け修正したものをさらにのトピックに載せます。
101
102
 
102
103
  ```C
103
104
  #include <stdio.h>

1

gdbの結果とその修正を追加

2023/11/01 11:52

投稿

daiwa
daiwa

スコア0

test CHANGED
File without changes
test CHANGED
@@ -96,7 +96,8 @@
96
96
  return 0;
97
97
  }
98
98
  ```
99
- SIZE×SIZEのある規則に則って生成された行列A、Bに対してC=ABを求めるコードです。このコードはベースとなるもので、SIZEに定義する数字以外は手を加えません。このコードをpthread.hを用いて並列化する課題です。元のコードをベースに自分で書いたものが以下です。
99
+ SIZE×SIZEのある規則に則って生成された行列A、Bに対してC=ABを求めるコードです。このコードはベースとなるもので、SIZEに定義する数字以外は手を加えません。このコードをpthread.hを用いて並列化する課題です。~~元のコードをベースに自分で書いたものが以下です。~~
100
+ gdbの結果受けさらに修正したものを下に載せます。
100
101
 
101
102
  ```C
102
103
  #include <stdio.h>
@@ -238,9 +239,143 @@
238
239
  ggc -Wall -lpthreadでのコンパイルは通過してます。ただSIZEを大きくするとセグメンテーションエラーが出ます。具体的に境界値を探せていませんが、500程度なら出力でき、1000はセグメ出ます。元のコードは1024でも出力可能です。
239
240
  セグメテーションエラーの原因を教えて頂きたいです。
240
241
 
241
- ### 自力でできなかった理由
242
+ ### ~~自力でできなかった理由~~(コメントのおかげで解決しました!)
242
- gdbを使って自力での特定を試みたのですが-gでコンパイルしてもディレクトリにcoreファイルが見つからない→そもそもコアダンプがでない(ただSegmentation faultのみ表示)→ulimitのコマンドが見つからないと言われるといった状態でこっちも手詰まりです…。セグメの原因追及と同時に、こちらも色々調べてる最中です。
243
+ ~~gdbを使って自力での特定を試みたのですが-gでコンパイルしてもディレクトリにcoreファイルが見つからない→そもそもコアダンプがでない(ただSegmentation faultのみ表示)→ulimitのコマンドが見つからないと言われるといった状態でこっちも手詰まりです…。セグメの原因追及と同時に、こちらも色々調べてる最中です。~~
244
+
243
-
245
+ ### gdbの結果受け修正
246
+ (gdb) frame 0
247
+ #0 0x0000000000400a49 in main () at matmul-th.c:108
248
+ 108 init_a(a,0,SIZE);
249
+ けっきょく何がダメなのからず。ただinit_aは仕様変更する必要無いことに気づき、元のコードのものをそのまま使用。合わせて一部変更
250
+ ```C
251
+ #include <stdio.h>
252
+ #include <stdlib.h>
253
+ #include<pthread.h>
254
+
255
+ #define SIZE 1000
256
+ #define PRINT_SIZE 8
257
+ #define THREAD_NUM 4
258
+
259
+ #include <pthread.h>
260
+ typedef struct {
261
+ int start, end, ans[SIZE][SIZE];
262
+ } arg_t;
263
+
264
+
265
+ // matrix[row][col]
266
+ int a[SIZE][SIZE], b[SIZE][SIZE], c[SIZE][SIZE];
267
+
268
+ //分割なし。aを一個だけ生成して範囲指定して使う。
269
+ void init_a(int mat[SIZE][SIZE]){
270
+ int row, col;
271
+ for (row = 0 ; row < SIZE ; row++){
272
+ for (col = 0 ; col < SIZE ; col++){
273
+ mat[row][col] = row+1;
274
+ }
275
+ }
276
+ }
277
+ void init_b(int mat[SIZE][SIZE]){
278
+ int row, col;
279
+ for (row = 0 ; row < SIZE ; row++){
280
+ for (col = 0 ; col < SIZE ; col++){
281
+ mat[row][col] = row+col+1;
282
+ }
283
+ }
284
+ }
285
+
286
+ void print_matrix_sub(int mat[SIZE][SIZE], int size, int abbr, int start_row){
287
+ int row, col;
288
+
289
+ for (row = start_row ; row < start_row+size ; row++){
290
+ for (col = 0 ; col < size ; col++){
291
+ printf("%4d ", mat[row][col]);
292
+ }
293
+ if (abbr){
294
+ printf(" ... ");
295
+ for (col = SIZE-size ; col < SIZE ; col++){
296
+ printf("%4d ", mat[row][col]);
297
+ }
298
+
299
+ }
300
+ printf("\n");
301
+ }
302
+ }
303
+
304
+ void print_matrix(int mat[SIZE][SIZE]){
305
+ int size, abbr;
306
+
307
+ if (SIZE > PRINT_SIZE){
308
+ size = PRINT_SIZE/2;
309
+ abbr = 1;
310
+ }
311
+ else {
312
+ size = SIZE;
313
+ abbr = 0;
314
+ }
315
+
316
+ print_matrix_sub(mat, size, abbr, 0);
317
+ if (abbr){
318
+ printf(" ...\n");
319
+ print_matrix_sub(mat, size, abbr, SIZE-size);
320
+ }
321
+ }
322
+
323
+ void matmul(int a[SIZE][SIZE], int b[SIZE][SIZE], int c[SIZE][SIZE],int start,int end){
324
+ int row, col, k, s;
325
+ for (row = start ; row < end ; row++){
326
+ for (col = 0 ; col < SIZE ; col++){
327
+ s = 0;
328
+ for (k = 0 ; k < SIZE ; k++){
329
+ s += a[row][k]*b[k][col];
330
+ }
331
+ c[row][col] = s;
332
+ }
333
+ }
334
+ }
335
+
336
+ void Assmat(int vessel[SIZE][SIZE],int element[][SIZE],int start,int end){
337
+ int row,col;
338
+ for (row = start ; row < end ; row++){
339
+ for (col = 0 ; col < SIZE ; col++){
340
+ vessel[row][col] = element[row][col];
341
+ }
342
+ }
343
+
344
+ }
345
+
346
+ void *f(void *varg){
347
+ arg_t *arg = (arg_t *)varg;
348
+ //tmpは不要になったので削除
349
+ matmul(a,b,arg->ans,arg->start,arg->end);
350
+ return NULL;
351
+ }
352
+
353
+ int main(void){
354
+ int i;
355
+ init_a(a);
356
+ init_b(b);
357
+ printf("A\n");
358
+ print_matrix(a);
359
+ printf("\nB\n");
360
+ print_matrix(b);
361
+ pthread_t th[THREAD_NUM];
362
+ arg_t arg[THREAD_NUM];
363
+ for(i = 0;i < THREAD_NUM;i++){
364
+ arg[i].start = i*(SIZE/THREAD_NUM);
365
+ arg[i].end = (i+1)*(SIZE/THREAD_NUM);
366
+ //printf("%d to %d\n",arg[i].start,arg[i].end);
367
+ pthread_create(&th[i],NULL,f,&arg[i]);
368
+ }
369
+ for(i = 0; i<THREAD_NUM; i++){
370
+ pthread_join(th[i],NULL);
371
+ Assmat(c,arg[i].ans,arg[i].start,arg[i].end);
372
+ }
373
+ printf("\nC = AB\n");
374
+ print_matrix(c);
375
+ return 0;
376
+ }
377
+ ```
378
+ ただし状況変わらずです…。SIZEが大きいとセグメですし、やっぱりinit_a(a)が原因だと言われます。元のコードが大丈夫なのもよく分からないです…。
244
379
  ### 補足情報(FW/ツールのバージョンなど)
245
380
  OSはlinuxです。ただ学校配布の物をそのまま使ってるので詳しい環境設定は分かりません。
246
381