• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ARMプロセッサ,NEONの並列化について)

ARMプロセッサ,NEONの並列化について

このQ&Aのポイント
  • ARMプロセッサのNEONを用いてプログラムの並列化を試みていますがうまくいきません...一般的なCソースに対してループ内の配列に"__restrict"をつけて,遅くなってしまいます.またアセンブラを見てもNEON固有の命令が見つかりません.
  • NEONを用いたARMプロセッサの並列化についての質問です.NEONを使ったループ内の配列演算に"__restrict"をつけることで遅くなってしまいます.またアセンブラを確認したところ,NEON固有の命令が見つかりませんでした.どなたか解決策を教えていただけると助かります.
  • ARMプロセッサのNEONを使用したプログラムの並列化について質問です.NEONを使ったループ内の配列の演算に"__restrict"をつけると逆に遅くなってしまいます.アセンブラも確認したのですが,NEON固有の命令が見当たりません.どなたか原因や解決策をご教示いただけると幸いです.

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

> この場合,ポインタの初期化を行う必お湯はありますでしょうか. ポインタって、vmla()の中のa, x, y, zのことを指して言っていますか? もしそうなら、これらの変数はvmla()が呼ばれたときに値が既に与えられています。 その値をそのまま使いたいのであれば&pを代入する必要はありませんし、元の値を捨てて別のポインタで演算をしたいのであれば質問中にあるように改めて初期化する必要があります。 vmla()で何をやりたいのかは質問者さんにしか分かりません (とは言え、&pを代入するのはきっと間違っているだろうとは推測できます)。 もう一点気になるのはコンパイルオプションです。 http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.htmlを見ると-mhard-floatは-mfloat-abi=hardと同じ意味と書かれていますから、それと-mfloat-abi=softfpを同時に指定するのは矛盾していて意味がありません。

kukky
質問者

補足

返答どうもありがとうございます. おっしゃる通り,値が与えられますね. そもそもポインタの初期化をした理由は はじめにSegmentation faultしたためです. 原因を調べた際に,初期化をしないと ポインタが示すアドレスがかぶることがある云々 とあったためです. しかしすべてに&pではまずいですね. この場合は必要ないということでしょうか. ちなみに返答にありました通り,初期化をコメントアウトして 行いましたがどうも並列化の恩恵はありませんでした. また,オプションに関してですが,今回のgccが まだ-mfloat-abi=hardをサポートしていないため -mfloat-abi=softfpを指定しております. http://blog.kmckk.com/archives/1565251.html -mhard-floatをつけると暗黙のうちに -mfloat-abi=hard になりますが、現状ARMのコンパイラではfloatのABIでhardはサポートされていません。なので、必ず -mhard-float を指定したら -mfloat-abi=softfp も指定する必要があります。 次にでてくるgcc 4.5 ではARMでの-mfloat-api=hardがサポートされるようです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

並列化どうこうの前に、vmla()の内容が間違っています。 a, x, y, zが全てpへのポインタで上書きされていて、main()で準備したa_val, x_val, y_val, z_valはvmla()での計算に使われていません。 pは配列ではないので、i≠0のときx[i]やa[i]にアクセスするのは正しくありません。

kukky
質問者

補足

返答ありがとうございます. 確かにvmlaがすべて上書きされてしまいますね... この場合,ポインタの初期化を行う必お湯はありますでしょうか. またある場合はvmlaの中にかいてはおかしいでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • opencvで特定の座標を指定しその座標の色変換

    #include <cv.h> #include <highgui.h> #include <stdio.h> /* グローバル変数 */ CvFont font; IplImage *img; int num1=0; int num2=0; int num3=0; int num4=0; /* プロトタイプ宣言 */ void on_trackbar1 (int val1); void on_trackbar2 (int val2); void on_trackbar3 (int val3); void on_trackbar4 (int val4); int main (int argc, char *argv[]) { img = cvLoadImage ( "bgr.jpg", CV_LOAD_IMAGE_COLOR); cvInitFont (&font, CV_FONT_HERSHEY_DUPLEX, 1.0, 1.0); cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE); cvCreateTrackbar ("X", "Image", 0, 255, on_trackbar1); cvCreateTrackbar ("Y", "Image", 0, 255, on_trackbar2); cvCreateTrackbar ("COLOR", "Image", 0, 255, on_trackbar3); cvCreateTrackbar ("-", "Image", 0, 100, on_trackbar4); cvShowImage ("Image", img); int x,y; uchar p[3]; for (y = 0; y < img->height; y++) { for (x = 0; x < img->width; x++) { p[0] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3]; // B p[1] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3+1]; // G p[2] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3+2]; // R p[0] = num3; p[1] = num3; p[2] = num3; } } cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&img); return 0; } /* コールバック関数 */ void on_trackbar1 (int val1) { num1 = val1; char str[64]; printf ( "X=%d Y=%d C=%d -=%d\n", val1, num2, num3, num4); } void on_trackbar2 (int val2) { num2 = val2; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, val2, num3, num4); } void on_trackbar3 (int val3) { num3 = val3; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, num2, val3, num4); } void on_trackbar4 (int val4) { num4 = val4; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, num2, num3, val4); } このプログラムで特定の座標の色変換をしたいのですがうまくいきません。 トラックバー1でX座標 トラックバー2でY座標 トラックバー3で変更後の色 を指定します。 実行すると画像は表示されますがトラックバーを動かしても変化がありません。トラックバーを動かした時にmain関数に戻れば良いと思い、思いつく限り試しましたが上手くいきません。 どなたかアドバイスお願いします。

  • 処理内容

    以下の3点について有識者へ伺いたいです。 (1)このプログラムが何をするものなのか (2)最後のfor文が無限ループしてしまう理由 (3)可能であれば、各行(各処理)が何をしているのかを教えていただければ嬉しいです。 #include <stdio.h> #include <string.h> #define NUM_HASH 10 char *hash_key[NUM_HASH]; unsigned char hash_val[NUM_HASH]; unsigned char calc_hash_value(const char *key) { int i; unsigned char val = 0; for (i = 0; key[i] != '\0'; i++) val += key[i]; return val; } int main(int argc, char *argv[]) { int i, cnt = 0; unsigned char val; for (--argc, ++argv; argc > 0 && cnt < sizeof(hash_val)/sizeof(hash_val[0]); --argc, ++argv, cnt++) { hash_key[cnt] = *argv; hash_val[cnt] = calc_hash_value(hash_key[cnt]); } for (val = 0; val < 256; val++) { for (i = 0; i < cnt; i++) { if (val == hash_val[i]) { printf("key = |"%s|"|n", hash_key[i]); printf("hash value = 0x%.2X|n", hash_val[i]); } } } return 0; }

  • c言語の難しい問題について

    (c言語の問題) 下記のプログラムを完成させ、キーボードから文字列を読み込み、-1文字ずらすことによって暗号化を行うプログラムを作りなさい。ただし、ピリオド、空白などはそのままにするようにすること。 例)this is a pen. sghr hr @ qdm. #include<stdio.h> #define CHAR_NUM 256 void angou( I ) { II } int main(void) { unsigned char text[CHAR_NUM]; char moji; int i; puts("暗号化する文字を入力しなさい。"); while((moji=getchar()) !=EOF){ text[i]=moji; i++; } angou(text i); printf("%s",text); return(0); } I、IIに入る文を書きなさい。 私はIには「char x[],int y」 IIには 「if('A'<x[i]<'Z' && 'a'<x[i]<'z') int j; for(j=0;j<y;j++) x[j]=x[j]-1 else」 といれたのですが、出力がうまくでません。どうすればいいのですか?

  • strcat(p,y)

    #include <iostream.h> void main(){ char x[29]="abcde"; char* y="~"; for(char *p=x+1, i=0; i<15; i++,p+=2) { *p=(char)(i+49); // x[奇数] に数字文字を入れる strcat(p,y); // 数字文字の後ろにチルダを付ける } cout << x << endl << x[29] << endl << x[30]; } ↓出力結果 ------------------------------------- a1~2~3~4~5~6~7~8~9~:~;~<~=~>~?~ ? ~ ------------------------------------- 1回目に動作する strcat(p,y) の処理を教えてください。 strcat(p,y) の処理をされる前は、 x[0]='a' x[1]='b' x[2]='c' x[3]='d' x[4]='e' ... となっていると思います。 1回目の strcat(p,y) で、x[1]='b' x[2]='~' x[3]='\0' x[4]='e' ... となると思うんだけど、この考えは合っていますか?

  • スロットルマシンぽいモノを作ろうとがんばってみましたが、

    スロットルマシンぽいモノを作ろうとがんばってみましたが、 止めた後、また動かす方法がわかりません。 kbhit()関数の使い方がわるいのでしょうか? なにとぞお知恵をお貸しください。 #include <stdio.h> #include <stdlib.h> #include <conio.h> void timer(double a); int main(void) { int i,a; char sev1[] = "0123456789"; char sev2[] = "4567890123"; char sev3[] = "7890123456"; char num[] = "000"; system("cls"); for(i=0;i<=10;i++){ timer(100000000); if(i==10){ i=0; } num[0]=sev1[i]; num[1]=sev2[i]; num[2]=sev3[i]; if(!kbhit()){ printf("%c%c%c\r",num[0],num[1],num[2]); } } return 0; } void timer(double a) { int i; for(i=0;i<a;i++){ ; } }

  • 配列の中身を入れ替える方法を教えてください

    配列の中身を入れ替える方法をどなたかおしえてください。下のプログラムはちゃんと実行されるんですが、いまいち納得できません。 特に・・・↓↓ void sort(int a[]) { int x,y,z,min; for(x=0;x<10;x++) { min=x; for(y=x;y<10;y++) { if(a[min]>a[y]) { min=y; } } z=a[min]; a[min]=a[x]; a[x]=z; } } 上の部分でなぜfor文を2回使うのか?2回目のfor文のところはなぜ y=xなのか?0ではいけないのか?よくわかりません。一番最後の入れ替え作業のところは納得できたんですが、for文のところがよくわからないのでどなたか分かる方教えてください! #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <time.h> void sort(int a[]) { int x,y,z,min; for(x=0;x<10;x++) { min=x; for(y=x;y<10;y++) { if(a[min]>a[y]) { min=y; } } z=a[min]; a[min]=a[x]; a[x]=z; } } int main(int argc, char* argv[]) { int a[10],b,c; srand((unsigned)time(NULL)); for(b=0;b<10;b++) { a[b]=rand(); c=a[b]; printf("a[%d]=%d\n",b,a[b]); } sort(a); for(b=0;b<10;b++) { printf("小さい順a[%d]=%d\n",b,a[b]); } return 0; }

  • C言語の質問です。

    C言語の質問です。 C言語で、PCの時間を、キーボードで入力した好きな秒数ごとに表示するプログラムを作りたいのですが、どうしても1秒ごとになってしまいます。ここまで作ったのですが、あとどのようにすればよろしいでしょうか? #include <stdio.h> #include <time.h> #include <string.h> int a2i(char x); main() { time_t jikoku; char t[30]; int h,m,s,so=0; int x,a; printf("秒数xを入力"); scanf("%d",&x); while(1){ for(a=0;a<x;a++){ time(&jikoku); strcpy(t,ctime(&jikoku)); h=a2i(t[11])*10+a2i(t[12]); m=a2i(t[14])*10+a2i(t[15]); s=a2i(t[17])*10+a2i(t[18]); if(s!=so+a){ printf("%d:%d:%d\n",h,m,s); so=s; } } } } int a2i(char x) { return(x-'0'); }

  • c言語 プログラミング

    以下のプログラムで分からないところがあります。 数式をxpyの形式で入力して、(x,y:整数、p:x,-,*,/のいずれかの演算記号) 答えを表示するというプログラムなのですが、 5行目と9行目にある”-'0'”の意味が分からないので教えてください。 01: int x=0,y=0,z,i;char a[30],p; 02: printf("式を入力してください。:);gets(a); 03: for(i=0;a[i];i++) 04:  if('0'<=a[i] && a[i]<='9') 05:   x=10*x+a[i]-'0'; 06:  else{p=a[i]-'0';break;} 07: for(i++;a[i];i++) 08:  if('0'<=a[i] && a[i]<='9') 09:   y=10*y+a[i]-'0'; 010: switch(p){ 11:  case '+':z=x+y;break; 12:  case '-':z=x+y;break; 13:  case '*':z=x*y;break; 14:  case '/':z=x/y;break; 15:  default:puts("入力エラーです。");return 0; 16: } 17: printf("%d%c%d=%d\n",x,p,y,z); よろしくお願いします。(読みにくかったらメモ帳などにコピペしてください)

  • ハノイの塔

    ★自分が理解している事 「(n-1)ハノイが解けると仮定するとnハノイも解けること」 は理解できます。 そして数学的帰納法によりすべての自然数についてハノイは「解ける」 ここまではわかります。 ★わからないのは、その「解き方」です。 「解ける」ことはわかるのですが「解き方」がわからないのです。 何故このプログラムで正解が表示されるのかが理解できないのです。 確かに、紙と鉛筆でプログラムの流れを追っていくと解けています。 しかし、何でこのプログラムで解けるのかがわからないのです。 棒xは出発点 棒yは目的地 棒zは作業棒 です。 (n-1)ハノイをひとかたまりと考え、作業棒Zに移す。 nハノイを目的地Yに移す。 (n-1)ハノイをひとかたまりと考え、目的地Yに移す。 そんな説明で確かに納得した気になりはします。 しかしこのプログラムでは(n-2)以下の場合についてはいっさい語っていません。 何かだまされてる気がします。 このプログラムでは(n-1)について語っていますが (n-2)以下については全く語っていません。 数学的帰納法により「解ける」ことは証明済みですが、 「その解き方」がこのプログラムでよいという「証明」はありますでしょうか? 理解のコツはありますでしょうか? よろしくお願いいたします。 #include<stdio.h> #include<stdlib.h> void hanoi(int n, char x, char y, char z) { if(n==0) {/* 何もしない */} else { hanoi(n-1,x,z,y); printf("%c->%c,",x,y); hanoi(n-1,z,y,x); } } int main(void) { int num; scanf("%d",&num); hanoi(num,'A','B','C'); return 0; }

  • オブジェクト(メモリ)のアドレスについて

    ■C++言語を勉強中です。 ■ポインター関係でオブジェクトのアドレスを求めています。 ■参考にC言語とC++言語で求めてみました。 ■ところが、C++プログラムでchar型のアドレスが表示されません。 ■C言語では表示されます 「質問」理由が分かりません、C++初心者です、宜しくお願いします。 //オブジェクトのアドレス //C++言語 #include <iostream> using namespace std; int main() { char x;      int y; double z; cout << "xのアドレス :" << &x << '\n'; cout << "yのアドレス :" << &y << '\n'; cout << "zのアドレス :" << &z << '\n'; return 0; } /* //C言語 #include <stdio.h> int main() { char x; int y; double z; printf("xのアドレス :%p \n",&x); printf("yのアドレス :%p \n",&y); printf("zのアドレス :%p \n",&z); return 0; } */