乱数関数のベクトル化

HPCインテル® DPC++/C++ コンパイラーインテル® Fortran コンパイラー

この記事は、インテル® デベロッパー・ゾーンに掲載されている「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

次のステップ

インテル® アーキテクチャー上にアプリケーションを移植してチューニングを行うには、次の記事にある各リンクのトピックを参照してください。アプリケーションのパフォーマンスを最大限に引き出すために必要なステップを紹介しています。

ベクトル化の基本」に戻る

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

タイトルとURLをコピーしました