2

私が作成したルーチンのコード チューニングに取り組んでおり、その一部で同時に実行できる 2 つの行列乗算を実行しています。現在、最初の DGEMM で (Intel の MKL ライブラリから) DGEMM を呼び出し、次に 2 番目の DGEMM を呼び出します。これにより、呼び出しごとにマシンの 12 コアすべてが使用されます。それぞれ 6 つのコアを使用して、両方の DGEMM ルーチンを同時に実行したいと考えています。これは簡単なことだと思いますが、これを達成する方法を見つけたり理解したりすることができませんでした。私が抱えている主な問題は、OpenMP が 1 つのスレッドから DGEMM ルーチンを呼び出さなければならないが、呼び出しごとに 6 を使用できることです。この状況に最適なディレクティブはどれですか? ネストされたプラグマが必要ですか?

したがって、より一般的な注意として、(私の場合は 12 個の) コアをセットに分割し、セット内のすべてのスレッドを使用する 1 つのスレッドからルーチンを実行するにはどうすればよいでしょうか。

ありがとう!

4

1 に答える 1

2

最も近い方法は、OpenMP 並列領域を 2 つのスレッドのチームで実行し、各スレッドから MKL を呼び出すことです。MKL でネストされた並列処理を有効にし (動的スレッドを無効にすることにより)、MKL スレッドの数を 6 に固定し、Intel のコンパイラ スイートを使用してコードをコンパイルする必要があります。MKL 自体は OpenMP を使用してスレッド化されていますが、Intel の OpenMP ランタイムです。GCC などの別のコンパイラを使用した場合、その OpenMP ランタイムは Intel のものと互換性がないことが判明する可能性があります。

言語を指定していないので、Fortran と C/C++ の 2 つの例を示します。

フォートラン:

call mkl_set_num_threads(6)
call mkl_set_dynamic(0)

!$omp parallel sections num_threads(2)
!$omp section
   call dgemm(...)
!$omp end section
!$omp section
   call dgemm(...)
!$omp end section
!$omp end parallel sections

C/C++:

mkl_set_num_threads(6);
mkl_set_dynamic(0);

#pragma omp parallel sections num_threads(2)
{
    #pragma omp section
    {
        cblas_dgemm(...)
    }
    #pragma omp section
    {
        cblas_dgemm(...)
    }
}

一般に、MKL のスレッドのサブセットを作成することはできません (少なくとも私の現在の理解では)。各 DGEMM 呼び出しは、グローバルに指定された数の MKL スレッドを使用します。MKL 操作は CPU のキャッシュ サイズに合わせて調整される可能性があり、2 つの行列乗算を並列に実行しても効果がない可能性があることに注意してください。2 つのヘキサコア CPU を備えた NUMA システムを使用しており、それぞれに独自のメモリ コントローラーがある場合 (これはあなたの場合だと思います)、データが配置される場所に注意し、スレッドのバインド (ピニング) を有効にする必要があります。コアに。

于 2013-01-18T13:55:32.083 に答える