Knights Landing (開発コード名) での Stream Triad のメモリー帯域幅の最適化

同カテゴリーの次の記事

NUMA ハードウェアによるパフォーマンスの向上

この記事は、インテル® デベロッパー・ゾーンに公開されている「Optimizing Memory Bandwidth in Knights Landing on Stream Triad」の日本語参考訳です。


この記事の PDF 版はこちらからご利用になれます。

概要

この記事は、インテル® Xeon Phi™ プロセッサー (開発コード名 Knights Landing) でピークメモリー帯域幅を評価する際の最適な手法を示します。ここでは、メモリー帯域幅を評価する際の業界標準である STREAM ベンチマークを使用します。

はじめに

STREAM ベンチマークは、4 つの単純なベクトルカーネル (Copy、Scale、Add、Triad) のメモリー帯域幅 (MB/秒) の制限と計算速度を評価するための合成ベンチマークです。ソースコードは http://www.cs.virginia.edu/stream/ (英語) から入手できます。STREAM は、HPC チャレンジ・ベンチマーク (HPCC) にも含まれています。

STREAM の使用条件

STREAM では、各配列は、実行に使用されるすべての最終レベルキャッシュ (LLC) の合計サイズの 4 倍以上か、100 万要素以上のいずれか大きいほうでなければなりません。

標準バージョンとチューニング済みバージョン

「Standard (標準)」バージョンの結果は、C または Fortran コードを倍精度データ型を使用してプロダクション・ハードウェア上で実行したものです。「Tuned (チューニング済み)」バージョンの結果は、倍精度データ型を使用して実行したものですが、(アセンブリー言語コードを含む) コードが変更されています。この記事では、標準バージョンの結果を使用します。

新しい MCDRAM メモリーの帯域幅を評価する場合、必要に応じてコードを変更することができます。特定のメモリーモードでは、MCDRAM は個別の NUMA ドメインとして認識されるため、(numactl のように) 実行時に標準の NUMA API で評価することができます。

Knights Landing (開発コード名) のメモリー・アーキテクチャーの概要

Knights Landing (開発コード名) には、DDR4 と MCDRAM の 2 種類のメモリーが搭載されています。

  • DDR4 は、低帯域幅で大容量のメモリーです。
  • MCDRAM は、高帯域幅で低容量 (最大 16GB) のメモリーで、Knights Landing (開発コード名) シリコンに統合されています。

MCDRAM は、3 次キャッシュ (メモリー・サイド・キャッシュ)、個別の NUMA ノード、またはこれらの組み合わせとして構成可能で、キャッシュ、フラット、ハイブリッドのいずれかのモードで利用できます。この記事では、フラットモードの DDR と MCDRAM でピークメモリー帯域幅を評価する手法を示します (ここで、DDR と MCDRAM は、別々の NUMA ノードとして認識される、個別のアドレス指定可能なメモリーです)。

ソース変更

メモリー割り当てを 2MB 境界でアライメントします。

静的割り当ての例:

static double a[N+OFFSET] __attribute__((aligned(2097152)));

動的割り当ての例:

a = (STREAM_TYPE *)_mm_malloc(sizeof(STREAM_TYPE)*(STREAM_ARRAY_SIZE+OFFSET),2097152);

上記を繰り返して、STREAM ベンチマークの 3 つの配列 a、b、c を割り当てます。

使用するコンパイラー・オプション (インテル® コンパイラー)

-mcmodel medium -shared-intel -O3 -xMIC-AVX512 -DSTREAM_ARRAY_SIZE=134217728 -DOFFSET=0 -DNTIMES=10 -qopenmp -qopt-streaming-stores always

注: STREAM の使用条件を満たす 1GB の配列を使用します。

メモリーモード: DDR4 + MCDRAM フラット (アドレス指定可能)

  • フラットモードでは、DDR4 と MCDRAM を個別にアドレス指定可能なメモリーとして利用できます。
  • 同じアプリケーションで DDR4 と MCDRAM を使用する場合、ソフトウェアの変更が必要になります。
  • アプリケーションのメモリー割り当てを DDR4 または MCDRAM のいずれかに設定するには、NUMA API を使用します。
    • この場合、ソフトウェアの変更は不要です。メモリー・フットプリントが MCDRAM メモリーに収まる場合、ユーザーは、NUMA API を使用してアプリケーション全体を MCDRAM で実行することができます。
  • DDR4 と MCDRAM がフラットモードなので、DDR と MCDRAM の帯域幅を個別に評価する必要があります。

DDR4 の帯域幅を評価する

  • インテル® Xeon Phi™ プロセッサー 7250 上で次のコマンドを実行します。
    export OMP_NUM_THREADS=68; export KMP_AFFINITY=scatter; numactl -m 0 ./stream

    システムで利用可能な NUMA ノードを特定するには、numactl -H コマンドを使用します。

MCDRAM の帯域幅を評価する (1 つ目の手法)

NUMA API を使用して実行時にすべてのメモリーを MCDRAM に割り当てて、フラットモードで MCDRAM の帯域幅を評価します。ソースの変更は不要です。

  • インテル® Xeon Phi™ プロセッサー 7250 上で次のコマンドを実行します。
    export OMP_NUM_THREADS=68; export KMP_AFFINITY=scatter; numactl -m 1 ./stream

MCDRAM の帯域幅を評価する (2 つ目の手法)

ソースを変更して、MEMKING/HBW API を使用します。

以下は、STREAM の標準のメモリー割り当てです。

static STREAM_TYPE a[STREAM_ARRAY_SIZE+OFFSET],
 b[STREAM_ARRAY_SIZE+OFFSET],
 c[STREAM_ARRAY_SIZE+OFFSET];

例えば、次のように MCDRAM (HBM) にメモリーを割り当てます。

hbw_posix_memalign ((void **)&a, 2097152, sizeof(STREAM_TYPE) * (STREAM_ARRAY_SIZE + OFFSET)
hbw_posix_memalign ((void **)&b, 2097152, sizeof(STREAM_TYPE)* (STREAM_ARRAY_SIZE + OFFSET)
hbw_posix_memalign ((void **)&c, 2097152, sizeof(STREAM_TYPE) * (STREAM_ARRAY_SIZE + OFFSET)

上記のように、hbw_posix_memalign(void **memptr, size_t alignment, size_t size) 構文を使用します。

  • 次のコマンドを実行します。
    export OMP_NUM_THREADS=68; export KMP_AFFINITY=scatter; ./stream_hbw_malloc

まとめ

MCDRAM は Knights Landing (開発コード名) で必要な高帯域幅を提供します。メモリー構成ごとに帯域幅が異なるため、それぞれのモードで評価する必要があります。

インテル® Xeon Phi™ プロセッサー 7250 で予測される STREAM Triad のメモリー帯域幅 (GB/秒):

クラスターモード: クアドラント (4 分割)、メモリーモード: DDR + MCDRAM フラット

MCDRAM フラット DDR4 フラット
約 475 ~ 490GB/秒 約 90GB/秒

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

関連記事