• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:openMPにしたいのですがお手伝いください。)

openMPによる並列化についての質問

ki073の回答

  • ki073
  • ベストアンサー率77% (491/634)
回答No.3

No.1の補足について まず外側のforのindiv1の値がどう変わっていくか見てみます。 indiv1=list->next_indiv; 最初の値 indiv1=indiv1->next_indiv; 二回目の値 indiv1=indiv1->next_indiv; 三回目の値 (略) の様にindiv1の値が変わっていきますよね。 それ例えばindiv[]という配列を用意しておき(No.1ではindiv0と書きましたが気が変わったのでindivにしました) indiv1=list->next_indiv; 最初の値 indv[0]=indiv1; indiv1=indiv1->next_indiv; 二回目の値 indv[1]=indiv1; indiv1=indiv1->next_indiv; 三回目の値 indv[2]=indiv1; の様にindvに代入をしておきます。これは質問欄の外側のforの前にやっておきます。ここではindivに代入する以外のことはやりません。 (indivの領域を予め確保しておく必要がありますが) その後で、 質問欄の外側のforに入ります。その時にはindiv1の値が全て決っていますので、 for(i=0; i<n ; i++){ sum = 0.0; for(j=0; j<n; j++){ sum += weight( distance(indiv[i], indiv[j]) ); } indiv[i]->local_density = sum; } のような感じになるように思いますが。 (indiv2もindiv1と同じ値をとりますよね) nはindivの有効なデータの大きさですが。

asuka_1026
質問者

補足

ki073さんありがとうございます!! 理解することができました♪ 時間が掛かってしまい申し訳ございません。・。 で、書いてみたのですが void calc_local_density(INDIVIDUAL *list){ INDIVIDUAL *indiv1, *indiv2, *indiv[9990000]; double sum; int i,j; float count; count=0; indiv1=list->next_indiv; for(i=0; indiv1; i++){ indiv[i]=indiv1; indiv1=indiv1->next_indiv; count++; } for(i=0; i<=count; i++){ sum = 0.0; for(j=0; j<=count; j++){ sum += weight( distance(indiv[i], indiv[j]) ); } indiv1->local_density = sum; } } 「セグメンテーション違反です」といわれてしまいました(~_~;) 配列がいけなかったのでしょうか??

関連するQ&A

  • openMPにしたいのですが

    #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include "dSFMT.h" #include <sys/time.h> #include <omp.h> #define T_END 100 #define BIRTH_RATE 1.0 #define DEATH_RATE 0.1 #define ALLEE_EFFECT 0.5 #define T_DENSITY 10.0 #define PROPAGULE_SIZE 5 #define SD_INTERACTION 1.0 #define SD_DISPERSAL 1.0 struct timeval start_timeval,end_timeval; int getutimer (struct timeval *start,struct timeval *end) { return ( ((int)end->tv_sec - (int)start->tv_sec)*1000000+((int)end->tv_usec - (int)start->tv_usec) ); } /* Properties of an individual */ typedef struct individual { double x, y, local_density; struct individual *next_indiv; }INDIVIDUAL; void calc_local_density(INDIVIDUAL *); double birth_rate(double); double death_rate(double); void birth(INDIVIDUAL*); void death(INDIVIDUAL*); void dispersal(INDIVIDUAL*); void display_list(INDIVIDUAL*); void write_to_file(INDIVIDUAL*, int, double, double); INDIVIDUAL *make_new_indiv(); INDIVIDUAL *add_next_indiv(INDIVIDUAL*); double weight(double); double distance(INDIVIDUAL*, INDIVIDUAL*); double sqr(double); int number_of_indivs(INDIVIDUAL*, double*, double*); dsfmt_t dsfmt; FILE *fp; int main(){ int seed; INDIVIDUAL *list_head, *indiv; int i, t; double xcenter, ycenter; gettimeofday(&start_timeval,NULL); seed=(long)time(NULL); dsfmt_init_gen_rand(&dsfmt, seed); fp = fopen("output.dat","w"); list_head = make_new_indiv(); indiv = list_head; for(i=0; i<PROPAGULE_SIZE; i++){ indiv = add_next_indiv(indiv); indiv->x = 0.0; indiv->y = 0.0; indiv->local_density = 0.0; } write_to_file(list_head, 0, 0.0, 0.0); for(t = 1; t <= T_END; t++){ dispersal(list_head); death(list_head); calc_local_density(list_head); birth(list_head); printf("Time = %d, Population size =%d\n", t, number_of_indivs(list_head, &xcenter, &ycenter)); write_to_file(list_head, t, xcenter, ycenter); } time(&time2); gettimeofday(&end_timeval,NULL); printf("%d %d, %d\n", time1, time2, time2 - time1); //?? printf("マイクロ秒:%d \n",getutimer(&start_timeval, &end_timeval)); return 0; } ・ ・ ・ ・ int number_of_indivs(INDIVIDUAL *list_head, double *xcenter, double *ycenter){ int count = 0; double xsum = 0.0, ysum = 0.0; INDIVIDUAL *indiv; for(indiv = list_head->next_indiv; indiv != NULL; indiv = indiv->next_indiv){ xsum += indiv->x; ysum += indiv->y; count++; } *xcenter = xsum/(double)count; *ycenter = ysum/(double)count; return count; } をopenMpにしたいのですがなかなか上手くいきません。 人口のシミュレーションなのですが、人が増えるたびに計算回数が増えるのでなんとかしたいのですが・・・ すべてのソースコードを記載ようとしたのですが、文字制限で載せられませんでした・・・ どうかお助けください。。 よろしくお願いいたします。

  • OpenMPのリダクション演算を自分でする方法

    OpenMPでプログラムを並列化しているのですが、以下の内積を並列化する際にreduction演算をしなくてはなりません for( i=0; i<N; i++ ){  r += x[i] * y[i]; } ↓ #pragma omp for reduction(+:r) for( i=0; i<N; i++ ){  r += x[i] * y[i]; } このように、for文に対してreduction節を入れてスレッド並列化するのが普通ですが、ここでBLASというライブラリを使いたいので、reductionを自分でしたいと考えています int INC = 1; int n = i_end - i_start; for( i=i_start; i<i_end; i++ ){  r += ddot_( &n, &(x[i_start]), &INC, &(y[i_start]), &INC ); } /* reduction here */ 0~N-1までの配列の要素を、自分でスレッドに分けて、i_start~i_endまでの要素の内積を各スレッドがddot_関数を使って計算します その後、reductionの計算をする必要があるのですが、一体どうすればreduction演算ができるのか分かりません どなたか分かる方、ご教授ください なお、スレッド並列版のBLASは使わない予定です あくまで、自分でスレッド並列化を行ない、その中で逐次版BLASを呼び出すという方向で考えています

  • 電卓のJavaScriptで

    大学でプログラミング基礎の講義を取っているのですが、そこで配られたテキストをなぜそうなるのか理解できなかったのでご教授お願いします。 電卓のJavaScriptなのですが、 <script language = "JavaScript"> count = 0; sum = 0; num = 0; flag = 0; list = new Array( "0", "0", "0", "0", "0" ); これはグローバル変数ですべてのfunctionに適応させるためのものだと 思うのですが、sum = 0;num = 0;というのはこのJavaScriptでどのような 意味を持ったものなのでしょうか? function clist( ) { for( i = 0 ; i < 5 ; i++ ) { list[ i ] = 0; } } このlist[ i ] = 0;というのは配列変数を使っているのですが、何を意味しているのでしょうか? また、このループを使うことによってどのような意味があるのでしょうか? function aclear( ) { count = 0; sum = 0; num = 0; flag = 0; clist( ); display.value = 0; } function calc1( ) { num = sum; clist( ); display.value = num; flag = 1; } function calc2( ) { num = sum; clist( ); display.value = num; flag = 2; } function calc3( ) { num = sum; clist( ); display.value = num; flag = 3; } function calc4( ) { num = sum; clist( ); display.value = num; flag = 4; } これらのcalc1からcalc4のなかの式の意味がよくわかりません(>_<) function equal( ) { if(flag == 1) { sum = num + sum; } else if(flag == 2) { sum = num - sum; } else if(flag == 3) { sum = num * sum; } else if(flag == 4) { sum = num / sum; } else { aclear( ); } display.value = sum; } function push1( ) { list[count] = 1; sum = list[count]; ↑ この部分は何を意味しているのでしょうか? for( i = 0 ; i < count ; i++ ) { temp = 1; for( j = i ; j < count ; j++) { temp = temp * 10; } sum += list[i] * temp; } count += 1; display.value = sum; } list[count] = 1; 以下同様に function push9 まで続く。 ちょっと長すぎるので、全部書きたかったのですが、無理でした。 正直さっぱりなので、困っています。

  • 和訳が分かりません。

    海外からwigを購入しているのですが、以下の和訳が分かりません。 分かる方がおりましたら、回答いただけるとありがたいです。 wigに関して仕様を決める項目の中に、   Individual Hair Strand Density という項目があり、その下に、   Define the density for each individual strand of hair. という説明文があり、その項目の選択肢の中に、   Standard (thin) or Thick というのがありました。 この上記に文・項目が理解できないので、分かる方がおりましたら回答いただけるとありがたいです。

  • 依存関係のあるfor文に対するOpenMP

    初めて質問させていただきます。これまでC言語を勉強していましたが、最近になってgccでも並列計算ができることを知り、その勉強を始めています。今、並列化の醍醐味を味わってみようと思い、組み合わせ数の計算(nCk)に取り組んでいます。まず、OpenMPを使っていない場合のプログラムを作りました。下記のプログラムが、それです。正しく動作していると思います。 しかし、このプログラムでは、for文の前後に依存関係があるため、このままでは並列化ができません。 if文を使って依存関係がないバージョンも試してみましたが、物凄く遅くなってしまいした。 このようなプログラムでOpenMPを活用するには、どのように工夫すれば良いでしょうか? どなたかご教授をお願いいたします。 追伸 下記のプログラムでは、100個の中から5つ取り出す際の組み合わせ数を計算しています。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define PARA_NUM 100 int main(void) { unsigned long long int i; unsigned int kk0, kk1, kk2, kk3, kk4; unsigned int parameter_num = 5; unsigned int pn[parameter_num]; for( i = 0; i < parameter_num; i++ ) { pn[i] = PARA_NUM - parameter_num + (i+1); } i = 0; for( kk0 = 0; kk0 < pn[0]; kk0++ ) { for( kk1 = kk0+1; kk1 < pn[1]; kk1++ ) { for( kk2 = kk1+1; kk2 < pn[2]; kk2++ ) { for( kk3 = kk2+1; kk3 < pn[3]; kk3++ ) { for( kk4 = kk3+1; kk4 < pn[4]; kk4++ ) { i++; } } } } } printf("%d_C_%d: %lld\n", PARA_NUM, parameter_num, i); return 0; }

  • MIPSアセンブラ言語について

    #include NULL 0 struct list{ struct list +next; int value; }; int sumvalue(sturuct list *head){ struct list *cur=NULL; int sum=0; for(cur = head; cur !=NULL; cur=cur->next){ sum += cur->value; } return sum; } このC言語で書かれた関数をMIPSアセンブラで記述するとどうなるのでしょうか?ポインタで混乱してます。

  • 電卓のJavaScript

    初心者で申し訳ないのですが、電卓のソースを作ってみたのですが、JavaScriptが間違っているためか「ページにエラーが発生しました」となり計算が行われません。 どのように、改変すればいいのでしょうか?どうかご教授お願いします。 <html> <head> <title> 電卓 </title> <script language = "JavaScript"> count = 0; sum= 0; flag =0; list = new Array( "0", "0","0","0","0",); function clist( ) { for( i = 0 ; i < 5 ; i++ ) { list[i] =0; } } function calc1() { num = sum; clist( ); display.value = num; flag = 1; } function calc2() { num = sum; clist( ); display.value = num; flag = 2; } function calc3() { num = sum; clist( ); display.value = num; flag = 3; } function calc4() { num = sum; clist( ); display.value = num; flag = 4; } function calc5() { clist( ); } function equal() { if(flag==1) { sum=num+sum; display.value=sum; clist( ); } else if(flag==2) { sum=num-sum; display.value=sum; clist( ); } else if(flag==3) { sum=num*sum; display.value=sum; clist( ); } else if(flag==4) { sum=num/sum; display.value=sum; clist( ); } } function push0( ) { list[count] = 0; sum = list[count]; for( i = 0 ; i < count ; i++ ) { temp=1; for( j = i ; j < count ; j++ ) { temp=temp*10; } sum+ =list[i]*temp; } count+=1; display.value=sum; } function push1( ) { list[count] = 1; sum = list[count]; for( i = 0 ; i < count ; i++ ) { temp=1; for( j = i ; j < count ; j++ ) { temp=temp*10; } sum+ =list[i]*temp; } count+=1; display.value=sum; } 同様に2~9 </script> </head> <body> <hr><br> <input type = "button" value ="7" onclick = "push7()">&nbsp <input type = "button" value ="8" onclick = "push8()">&nbsp <input type = "button" value ="9" onclick = "push9()">&nbsp&nbsp <input type = "button" value ="+" onclick = "calc1()">&nbsp<br><br> <input type = "button" value ="4" onclick = "push4()">&nbsp <input type = "button" value ="5" onclick = "push5()">&nbsp <input type = "button" value ="6" onclick = "push6()">&nbsp&nbsp <input type = "button" value ="-" onclick = "calc2()">&nbsp<br><br> <input type = "button" value ="1" onclick = "push1()">&nbsp <input type = "button" value ="2" onclick = "push2()">&nbsp <input type = "button" value ="3" onclick = "push3()">&nbsp&nbsp <input type = "button" value ="×" onclick = "calc3()">&nbsp<br><br> <input type = "button" value ="0" onclick = "push0()">&nbsp <input type = "button" value ="=" onclick = "equal()">&nbsp <input type = "button" value ="C" onclick = "calc5()">&nbsp&nbsp <input type = "button" value ="÷" onclick = "calc4()">&nbsp<br><br> <br><br><hr><br>&nbsp&nbsp&nbsp <input type = "text" size ="10" name = "display">&nbsp <br><br><hr><br> </body> </html>

  • freeでメモリが開放できません。。。

    以下のプログラムは、下記の入力データを構造体に格納し、平均身長と平均体重を求めて画面に出力するプログラムです。feeによるメモリの開放が動いていないようで、結果まで出力してくれるのですが、その直後エラー終了してしまいます。なにが悪いのか全く分かりません!!どなたかアドバイスをお願いしますm(__)m データファイル Sakuragi 189 83 みたいなデータが5組あります。 ソースプログラム #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct person{ char name[20]; int height; int weight; struct person *next; }LIST; LIST *ave(LIST *head); LIST *newLIST(void); int main(int argc,char *argv[]){ char namae[20]; int n=0,shinchou,taijuu; FILE *fp; LIST *head; LIST *p; LIST *np; LIST *npb; LIST *AVE; head = newLIST(); npb = head; if((fp=fopen(argv[1],"r"))==NULL){ printf("no file\n"); exit(1); } while(n != 5){ np = newLIST(); fscanf(fp,"%s %d %d",namae,&shinchou,&taijuu); strcpy(p->name,namae); np->height= shinchou; np->weight= taijuu; npb->next=np; npb=np; n++; } fclose(fp); AVE = ave(head); printf("%d\t%d\n",AVE->height,AVE->weight); for(p=head;p != NULL;p= p->next){ free(p); } return(0); } LIST *newLIST(){ LIST *p; p=(LIST*)malloc(sizeof(LIST)); p->next = NULL; return(p); } LIST *ave(LIST *head){ LIST *p,*pp; int h=0,w=0; for(p=head->next;p != NULL;p=p->next){ h += p->height; w += p->weight; } h = h/5; w = w/5; pp->height = h; pp->weight = w; return(pp); }

  • c言語の問題です。ファイルからデータを読み込み連結リストに記憶しソートするプログラムです。お願いします

    ソート部分がどうしてもできません。 またソートは以下のアルゴリズムで行うものです 与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。 1.リストAの要素の中で、最大値をもつ要素Cを探す。 2.要素CをリストAから削除する。 3.要素CをリストBの先頭に挿入する。 4.リストAが空であれば終了。空でなければ 1. にもどる。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct physical Physical; struct physical { char name[41]; int age; float height; float weight; Physical *next; }; void read_data(char *file,Physical *p,Physical *tail); int comp1(const Physical *, const Physical *); int comp2(const Physical *, const Physical *); int comp3(const Physical *, const Physical *); int comp4(const Physical *, const Physical *); void sort(char *arg,Physical *p,Physical *q); Physical *listsort(Physical *p, int (*compar)(const void *, const void *)); int main(void) { char s[20],t,u[20]; Physical *p,*tail,*q; p=malloc(sizeof(Physical)); q=malloc(sizeof(Physical)); tail=malloc(sizeof(Physical)); while(1) { printf("CMD>"); fflush(stdout); fgets(s,20,stdin); sscanf(s,"%c %s",&t,u); switch(t){ case 'q':exit(0); case 'r':read_data(u,p,tail); break; case 's':sort(u,p,q); break; case 'd': while(q!=NULL) { printf("%s %d %.1f %.1f ",q->name,q->age,q->height,q->weight ); q=q->next;} break; } } free(p); return 0; } void read_data(char *file,Physical *p,Physical *tail){ FILE *fp; char string[100]; Physical header; tail=&header; header.next = NULL; p->next = NULL; tail->next = p; tail = p; if ((fp = fopen(file, "r")) == NULL) { exit(1); } while(fgets(string,sizeof(string),fp)!= NULL) { sscanf(string,"%s %d %f %f",p->name,&p->age,&p->height,&p->weight); Physical *tail2; tail2=malloc(sizeof(Physical)); tail2->next=NULL; p->next=tail2; p=tail2; } fclose(fp); } void sort(char *arg,Physical *p,Physical *q){ if(strcmp(arg,"name") == 0) q=listsort(p,(int(*)(const void*, const void*))comp1); if(strcmp(arg,"age") == 0) q=listsort(p,(int(*)(const void*, const void*))comp2); if(strcmp(arg,"height") == 0) q=listsort(p,(int(*)(const void*, const void*))comp3); if(strcmp(arg,"weight") == 0) q=listsort(p,(int(*)(const void*, const void*))comp4); } Physical *listsort(Physical *p,int (*compar)(const void *, const void *)){ Physical *q, *max,*s,*head; s=malloc(sizeof(Physical)); head=malloc(sizeof(Physical)); head=NULL; while(p->next){max = p, q = p->next; while( q->next ) { if( compar(q->next,max->next) ) max = q; q = q->next;} s=max->next; max->next=max->next->next; if(head==NULL) {head=s;} s->next=s; } return head; } int comp1(const Physical *a, const Physical *b){ return (strncmp(a->name,b->name,sizeof(Physical))); } int comp2(const Physical *a, const Physical *b){ if(a->age > b->age) return 1; else return 0; } int comp3(const Physical *a, const Physical *b){ if(a->height > b->height) return 1; else return 0; } int comp4(const Physical *a, const Physical *b){ if(a->weight > b->weight) return 1; else return 0; }

  • c言語つくってみました

    #include<stdio.h> #define N 5 struct MEMBER{ int no; char name[8+1]; int run; int jump; int power; int sum; double avg; }; void Calc_Sum(struct MEMBER *data) { data->sum=data->run+data->jump+data->power; return(0); } void Calc_Avg(struct MEMBER *data) { data->avg=data->sum/3.0; return(0); } void Display_Data(struct MEMBER data) { printf("---判定---\n"); printf("背番号:%5d\n",data.no); printf("名前:%5s\n",data.name); printf("走力 :%5d 点数\n",data.run); printf("跳躍力:%5d 点数\n", data.jump); printf("筋力 :%5d 点数\n", data.power); printf("総計 :%5d 点数\n", data.sum); printf("平均 :%5.1f 点数\n", data.avg); return(0); } int main(void) { int i; struct MEMBER member[N] ={{51,"イチロー",95,95,80,0,0}, {55,"松井秀喜",70,80,90,0,0}, {18,"松坂大輔",75,75,80,0,0}, {18,"黒田博樹",80,85,85,0,0}, {19,"上原浩治",85,85,85,0,0}, }; struct MEMBER *p=member; /*総計の算出*/ for(i=0;i<N;i++) Calc_Sum(p+i); /*平均の算出*/ for(i=0;i<N;i++) Calc_Avg(p+i); /*結果の出力:*/ for(i=0;i<N;i++) Display_Data(member[i]); return(0); } 以上のようなのc言語をつくりました。 他に関数を2つ使用しなければならないのですが アドバイスよろしくお願い致します。