インテル® C++ コンパイラー XE 13.1 ユーザー・リファレンス・ガイド
このトピックは、インテル® メニー・インテグレーテッド・コア (インテル® MIC) アーキテクチャーにのみ適用されます。
オフロード・ランタイム・システムは CPU とコプロセッサーの同じ仮想アドレスでメモリーのセクションを保持します。_Cilk_shared キーワードを使用することで、この共有メモリーを次のように使用できます。
コンパイラーは、次のような共有変数を割り当てます。
共有変数のアドレスは同じであるため、同じアドレス共有変数へのポインターには CPU とコプロセッサーで同じ値が含まれます。このため、オフロードコードをリンクされたデータ構造で容易に操作できます。メモリーは、オフロードの呼び出し位置でのみ CPU とコプロセッサー間で同期されます。
インテル® MIC アーキテクチャー上で実行するようにコンパイルする場合は、共有変数を条件付きで制御できません。
変数が _Cilk_shared とマークされると、変数のメモリー割り当てはスタティックではなくダイナミックで行われます。ホストが割り当てるメモリーは、ホストとコプロセッサーが共有するメモリー空間内のみです。 プログラムをコンパイルすると、ホストは共有メモリーをダイナミックに作成するコードを生成します。このため、ホストが共有変数を見ない場合、変数のメモリーを割り当てません。メモリーが共有空間に割り当てられないため、コプロセッサーがこのメモリーにアクセスしようとすると、不正なアクセスが発生します。
ホストは共有変数にメモリーを割り当てるため、ホストが変数を使用しない場合でも、ホストが変数を見えるようにする必要があります。
例えば、次のコードは変数がコプロセッサー用に条件付きでコンパイルされているため正しくありません。このため、ホストで変数のメモリーを割り当てるコードは生成されません。
#ifdef __MIC__ _Cilk_shared int res; #endif
変数をコプロセッサー用に条件付きでコンパイルすると、ホストは変数にアクセスしないため、_Cilk_shared キーワードは必要ありません。 ホストとコプロセッサー間でデータを共有する場合のみ、_Cilk_shared を使用します。
_Cilk_shared および _Cilk_offload キーワードで操作する共有メモリーの割り当てと解放には、次の関数を利用します。 これらの関数は、インテル® MIC アーキテクチャー・ベースのハードウェアがシステムにない場合、またはインテル® MIC アーキテクチャー・ドライバーがロードされていない場合、標準の malloc または free バージョンを使用します。
デフォルトでは、標準 C++ ライブラリーのコンテナーは非共有メモリーを割り当てます。コンテナーのオブジェクトが _Cilk_shared とマークされると、そのデータメンバーは共有メモリーに割り当てられます。 ただし、データがアクセスするメモリーは共有されません。このメモリーを共有できるようにするため、shared_allocator<T> クラス・テンプレートを使用します。 shared_allocator<T> クラス・テンプレートは offload.h で定義されています。
#include <vector> #include <offload.h> #include <stdio.h> using namespace std; // オフロードの共有アロケーターを使用するための typedef vector typedef vector<int, __offload::shared_allocator<int> > shared_vec_int; _Cilk_shared shared_vec_int * _Cilk_shared v; _Cilk_shared int test_result() { int result = 1; for (int i = 0; i < 5; i++) { if ((*v)[i] != i) { result = 0; } } return result; } int main() { int result; // new を使用して共有メモリー空間にオブジェクトを構築 v = new (_Offload_shared_malloc(sizeof(vector<int>))) _Cilk_shared vector<int, __offload::shared_allocator<int> >(5); for (int i = 0; i < 5; i++) { (*v)[i] = i; } result = _Cilk_offload test_result(); if (result != 1) printf("Failed\n"); else printf("Passed\n"); return 0; }