乱数関数のベクトル化

同カテゴリーの次の記事

インテル® Xeon Phi™ コプロセッサー向けネイティブ・アプリケーションのビルド

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Random Number Function Vectorization」の日本語参考訳です。


インテル® コンパイラー 13.0 では、drand48 乱数関数 (C/C++) と RANF / RANDOM_NUMBER 乱数関数 (Fortran) の自動ベクトル化がサポートされました。ベクトル化はインテル® Short Vector Math Library (SVML) によりサポートされます。以下に利用例を示します。

サポートされている C/C++ 関数:

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 のベクトル化

#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}; 

    // 乱数の初期シード値 
    seed48(&seed[0]); 

    for (i = 0; i < ASIZE; i++){ 
        rand_number[i] = drand48(); 
    } 

    // サンプル配列要素 p
    rintf("%f\n", rand_number[ASIZE-1]); 
    return 0; 
}

2. erand38 のベクトル化。シード値は引数として渡します。

#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]); 
    } 

    // サンプル配列要素 
    printf("%f\n", rand_number[ASIZE-1]); 
    return 0; 
}

3. lrand38 のベクトル化

#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}; 

    // 乱数の初期シード値 
    seed48(&seed[0]); 

    for (i = 0; i < ASIZE; i++){ 
        rand_number[i] = lrand48(); 
    }  

    // サンプル配列要素 
    printf("%ld\n", rand_number[ASIZE-1]); 
    return 0; 
}

4. nrand48 のベクトル化。シード値は引数として渡します。

#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]); 
    } 
  
    // サンプル配列要素 
    printf("%ld\n", rand_number[ASIZE-1]); 
    return 0; 
}

5. mrand48 のベクトル化

#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}; 

    // 乱数の初期シード値 
    seed48(&seed[0]); 

    for (i = 0; i < ASIZE; i++){ 
        rand_number[i] = mrand48(); 
    }

    // サンプル配列要素 
    printf("%ld\n", rand_number[ASIZE-1]); 
    return 0;
}

6. jrand48 のベクトル化。シード値は引数として渡します。

#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]); 
    }

    // サンプル配列要素 
    printf("%ld\n", rand_number[ASIZE-1]); 
    return 0;
}

Fortran のサポート:

Fortran では、次の関数をサポートします。

RANF()

RANDOM_NUMBER() 単精度

RANDOM_NUMBER() 倍精度

次のステップ

この記事は、「Programming and Compiling for Intel® Many Integrated Core Architecture」(英語) の一部「Random Number Function Vectorization」の翻訳です。インテル® Xeon Phi™ コプロセッサー上にアプリケーションを移植し、チューニングを行うには、各リンクのトピックを参照してください。アプリケーションのパフォーマンスを最大限に引き出すために必要なステップを紹介しています。

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

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

関連記事