この記事は、インテル® デベロッパー・ゾーンに掲載されている「Random Number Function Vectorization」(http://software.intel.com/en-us/articles/random-number-function-vectorization) の日本語参考訳です。
インテル® コンパイラー 13.0 以降では、drand48 乱数関数 (C/C++) と RANF / RANDOM_NUMBER 乱数関数 (Fortran) の自動ベクトル化がサポートされます。ベクトル化はインテル® Short Vector Math Library (SVML) によりサポートされます。
サポートされている C/C++ 関数:
1 2 3 4 5 6 | double drand48( void ); double erand48(unsigned short xsubi[3]); long int lrand48( void ); long int nrand48(unsigned short xsubi[3]); long int mrand48( void ); long int jrand48(unsigned short xsubi[3]); |
簡単な例:
1. drand48 のベクトル化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdlib.h> #include <stdio.h> #define ASIZE 1024 int main( int argc, char *argv[]) { int i; double rand_number[ASIZE] = {0}; unsigned short seed[3] = {155,0,155}; // Initialize Seed Value For Random Number seed48(&seed[0]); for (i = 0; i < ASIZE; i++){ rand_number[i] = drand48(); } // Sample Array Element printf ( "%f\n" , rand_number[ASIZE-1]); return 0; } |
2. erand48 のベクトル化 (シード値は引数渡し)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdlib.h> #include <stdio.h> #define ASIZE 1024 int main( int argc, char *argv[]) { int i; double rand_number [ASIZE] = {0}; unsigned short seed[3] = {155,0,155}; #pragma ivdep for (i = 0; i < ASIZE; i++){ rand_number[i] = erand48(&seed[0]); } // Sample Array Element printf ( "%f\n" , rand_number[ASIZE-1]); return 0; } |
3. lrand48 のベクトル化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdlib.h> #include <stdio.h> #define ASIZE 1024 int main( int argc, char *argv[]) { int i; long rand_number[ASIZE] = {0}; unsigned short seed[3] = {155,0,155}; // Initialize Value For Random Number seed48(&seed[0]); for (i = 0; i < ASIZE; i++){ rand_number[i] = lrand48(); } // Sample Array Element printf ( "%ld\n" , rand_number[ASIZE-1]); return 0; } |
4. nrand48 のベクトル化 (シード値 id は引数渡し)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdlib.h> #include <stdio.h> #define ASIZE 1024 int main( int argc, char *argv[]) { int i; long rand_number[ASIZE] = {0}; unsigned short seed[3] = {155,0,155}; #pragma ivdep for (i = 0; i < ASIZE; i++){ rand_number[i] = nrand48(&seed[0]); } // Sample Array Element printf ( "%ld\n" , rand_number[ASIZE-1]); return 0; } |
5. mrand48 のベクトル化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdlib.h> #include <stdio.h> #define ASIZE 1024 int main( int argc, char *argv[]) { int i; long rand_number[ASIZE] = {0}; unsigned short seed[3] = {155,0,155}; // Initialize Seed Value For Random Number seed48(&seed[0]); for (i = 0; i < ASIZE; i++){ rand_number[i] = mrand48(); } // Sample Array Element printf ( "%ld\n" , rand_number[ASIZE-1]); return 0; } |
6. jrand48 のベクトル化 (シード値は引数渡し)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdlib.h> #include <stdio.h> #define ASIZE 1024 int main( int argc, char *argv[]) { int i; long rand_number[ASIZE] = {0}; unsigned short seed[3] = {155,0,155}; #pragma ivdep for (i = 0; i < ASIZE; i++){ rand_number[i] = jrand48(&seed[0]); } // Sample Array Element printf ( "%ld\n" , rand_number[ASIZE-1]); return 0; } |
Fortran のサポート:
Fortran では、次の関数をサポートします。
1 2 3 4 5 | RANF() RANDOM_NUMBER() single precision RANDOM_NUMBER() double precision |
次のステップ
インテル® アーキテクチャー上にアプリケーションを移植してチューニングを行うには、次の記事にある各リンクのトピックを参照してください。アプリケーションのパフォーマンスを最大限に引き出すために必要なステップを紹介しています。
「ベクトル化の基本」に戻る
コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。