インテル® MKL 11.3 を使用した行列乗算チュートリアル
デフォルトでは、インテル® MKL は n スレッド使用します (n はシステムの物理コアの数)。この演習では、スレッド数を制限して dgemm のパフォーマンスの変化を測定することで、スレッド化がパフォーマンスに与える影響を説明します。
この演習では、mkl_set_num_threads ルーチンを使用してデフォルトのスレッド数を変更し、mkl_get_max_threads ルーチンを使用して最大スレッド数を決定します。
/* C ソースコードは dgemm_threading_effect_example.c を参照 */ printf (" Finding max number of threads Intel® MKL can use for parallel runs \n\n"); max_threads = mkl_get_max_threads(); printf (" Running Intel® MKL from 1 to %i threads \n\n", max_threads); for (i = 1; i <= max_threads; i++) { for (j = 0; j < (m*n); j++) C[j] = 0.0; printf (" Requesting Intel® MKL to use %i thread(s) \n\n", i); mkl_set_num_threads(i); printf (" Making the first run of matrix product using Intel® MKL dgemm function \n" " via CBLAS interface to get stable run time measurements \n\n"); cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, alpha, A, k, B, n, beta, C, n); printf (" Measuring performance of matrix product using Intel® MKL dgemm function \n" " via CBLAS interface on %i thread(s) \n\n", i); s_initial = dsecnd(); for (r = 0; r < LOOP_COUNT; r++) { cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, alpha, A, k, B, n, beta, C, n); } s_elapsed = (dsecnd() - s_initial) / LOOP_COUNT; printf (" == Matrix multiplication using Intel® MKL dgemm completed ==\n" " == at %.5f milliseconds using %d thread(s) ==\n\n", (s_elapsed * 1000), i); }
結果から、スレッド数が増加するとともに行列乗算の時間が減少していることが分かります。この演習を、mkl_get_max_threads で返されたスレッド数よりも多くのスレッド数で実行すると、物理コアよりも多くのスレッド数を使用したときにパフォーマンスが低下します。
dgemm の特定のパフォーマンス結果は、http://software.intel.com/en-us/articles/intel-mkl (英語) の [Details] タブで確認することができます。