インテル® C++ コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
このトピックは、インテル® メニー・インテグレーテッド・コア (インテル® MIC) アーキテクチャーをターゲットとする場合にのみ適用されます。
オフロード・ランタイム・システムは CPU とコプロセッサーの同じ仮想アドレスでメモリーのセクションを保持します。_Cilk_shared キーワードを使用することで、この共有メモリーを次のように使用できます。
この共有メモリーのアドレス範囲の変数を配置します。
関数が CPU とコプロセッサーの両方で定義されるように指定します。
コンパイラーは、次のような共有変数を割り当てます。
仮想アドレスが CPU とコプロセッサーで同じ
値があらかじめ定義されたポイントで CPU とコプロセッサー間で同期される
共有変数のアドレスは同じであるため、同じアドレス共有変数へのポインターには CPU とコプロセッサーで同じ値が含まれます。このため、オフロードコードをリンクされたデータ構造で容易に操作できます。メモリーは、オフロードの呼び出しでのみ CPU とコプロセッサー間で同期されます。
インテル® MIC アーキテクチャー上で実行するようにコンパイルする場合は、共有変数を条件付きで制御できません。
変数が _Cilk_shared と表記されると、変数のメモリー割り当てはスタティックではなくダイナミックで行われます。ホストが割り当てるメモリーは、ホストとコプロセッサーが共有するメモリー空間内のみです。プログラムをコンパイルすると、ホストは共有メモリーをダイナミックに作成するコードを生成します。このため、ホストが共有変数を見ない場合、変数のメモリーを割り当てません。メモリーが共有空間に割り当てられないため、コプロセッサーがこのメモリーにアクセスしようとすると、不正なアクセスが発生します。
ホストは共有変数にメモリーを割り当てるため、ホストが変数を使用しない場合でも、ホストが変数を見えるようにする必要があります。
例えば、次のコードは変数がコプロセッサー用に条件付きでコンパイルされているため正しくありません。このため、ホストで変数のメモリーを割り当てるコードは生成されません。
#ifdef __MIC__
_Cilk_shared int res;
#endif
変数をコプロセッサー用に条件付きでコンパイルすると、ホストは変数にアクセスしないため、_Cilk_shared キーワードは必要ありません。ホストとコプロセッサー間でデータを共有する場合のみ、_Cilk_shared を使用します。
デフォルトでは、コンパイラーは 2 つのバイナリーファイルをビルドします。
CPU バージョン: _Cilk_shared と表記されているかどうかに関係なく、ソースコードのすべての関数が含まれます。
ターゲットバージョン: ソースコードで _Cilk_shared と表記されている関数のみ含まれます。
CPU バージョンのみビルドするには、[Q]offload オプションの否定形を使用します。
_Cilk_shared および _Cilk_offload キーワードで操作する共有メモリーの割り当てと解放には、次の関数を利用します。これらの関数は、インテル® MIC アーキテクチャー・ベースのハードウェアがシステムにない場合、またはインテル® メニーコア・プラットフォーム・ソフトウェア・スタック (インテル® MPSS) がロードされていない場合、標準の malloc または free バージョンを使用します。
void *_Offload_shared_malloc(size_t size);
void *_Offload_shared_aligned_malloc(size_t size, size_t alignment);
_Offload_shared_free(void *p);
_Offload_shared_aligned_free(void *p);
デフォルトでは、標準 C++ ライブラリーのコンテナーは非共有メモリーを割り当てます。コンテナーのオブジェクトが _Cilk_shared と表記されると、そのデータメンバーは共有メモリーに割り当てられます。ただし、データがアクセスするメモリーは共有されません。このメモリーを共有できるようにするため、shared_allocator<T> クラス・テンプレートを使用します。shared_allocator<T> クラス・テンプレートは offload.h で定義されています。
#pragma offload_attribute (push, _Cilk_shared)
#include <vector>
#include <offload.h>
#pragma offload_attribute (pop)
#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;
}