1

私はxeon phiプログラミングを学ぼうとしています。

私はこのコードを CPU で実行しており、コプロセッサーで実行したい部分にオフロード プラグマを使用しています。

私はCPUでコンパイルしていて、 offloads を使用しているので、次を使用しています:

export MIC_ENV_PREFIX=MIC
export MIC_OMP_NUM_THREADS=120

スレッド番号を指定するため。

私の問題:

1) コードを実行すると、常に 40 個のスレッドが使用されていることが示されます。

2)コンパイルせずにコードを何度も実行すると、異なる時間結果が得られます。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#include <sys/time.h>

#include <cilk/cilk.h>
#include <cilk/reducer_opadd.h>


typedef CILK_C_DECLARE_REDUCER(float) reducer;


double dtime()
{
    double tseconds = 0.0;
    struct timeval mytime;
    gettimeofday(&mytime,(struct timezone*)0);
    tseconds = (double)(mytime.tv_sec + mytime.tv_usec*1.0e-6);
    return( tseconds * 1000 );
}

float openMPIntegration(

    int N,
    float * const ioA )
{

    float res = 0;

#if DOFFLOAD
    #pragma offload target (mic) 
    {
#endif

    #pragma omp parallel for reduction(+:res)
    for ( int i = 0; i < N; i++ )
    {
        res += ioA[ i ]; 
    }

#if DOFFLOAD
}
#endif

    return res;

}

float CilkIntegration(

    int N , 
    float * const ioA )
{


float res = 0;
#if DOFFLOAD
    #pragma offload target (mic) 
    {
#endif

    CILK_C_REDUCER_OPADD( sum, float , 0);
    CILK_C_REGISTER_REDUCER(sum);

    cilk_for ( int i = 0; i < N; i++ )
    {
        REDUCER_VIEW(sum) += ioA[ i ];
    }

    res = sum.value;
    CILK_C_UNREGISTER_REDUCER(sum);

#if DOFFLOAD
}
#endif

    return res;
}    

int main()
{
    int NbOfThreads;
    double tstart, tstop, ttime;

    int N = 1000000;
    float * A = (float*) _mm_malloc( N * sizeof(*A) , 32 );

    //fill A
    for ( int i = 0; i < N; i++ )
        A[ i ] = i;

#if DOFFLOAD
    #pragma offload target (mic)
#endif

    #pragma omp parallel
    #pragma omp master
    NbOfThreads = omp_get_num_threads();

    printf("\nUsing %d threads\r\n",NbOfThreads);

    tstart = dtime();   

    float openMPRes = openMPIntegration( N , A );

    tstop = dtime();    
    ttime = tstop - tstart;
    printf("\nopenMP integration = %10.3lf msecs \t value = %10.3f", ttime ,openMPRes);


    tstart = dtime();   
    float CilkRes = CilkIntegration( N , A );

    tstop = dtime();    
    ttime = tstop - tstart;
    printf("\nCilk   integration = %10.3lf msecs \t value = %10.3f", ttime,CilkRes);

    printf("\n");
    _mm_free( A );

    return 0;

}

私はコンパイルしています:

icc -std=c99 -DOFFLOAD -openmp -qopt-report -O3 xeon.c -o xeon
4

1 に答える 1

1

これは厳密には OpenMP に関する質問ではありません。異なる並列ランタイム モデルの推奨されない組み合わせが含まれているためです。また、openmp の標準化されたオフロード構文を使用していないと思います。簡単に言えば、OpenMP と cilkplus 並列ランタイム モデルの組み合わせを推奨する実装はありません。それを超える次のステップは、典型的な OpenMP モデルでは、デフォルトで、OpenMP 外部のスレッド モデルへのハードウェア スレッド コンテキストの可用性を一時的にブロックすることです (通常はデフォルトで 0.200 秒)。cilkplus レデューサーよりも omp リダクションを使用する方がスタイル的に一貫しているように見えますが、現在の実装では、ショーを停止する決定ではない可能性があります。Intel オフロード モデルを使用して、openmp の標準オフロード構文と非標準オフロード構文の両方を使用できるようにしていると思います。

于 2015-04-01T11:32:07.087 に答える