ラムダ、関数オブジェクト、および制限関数の使用
アクセラレータを実行する、AMP の C++ コードの呼び出しで引数として指定されて、 parallel_for_each メソッド。その引数として、ラムダ式または関数オブジェクト (ファンクタ) のいずれかを指定できます。さらに、ラムダ式または関数オブジェクトを C++ のストレージ ・ システムによって制限されている関数を呼び出すことができます。このトピックでは、配列加算アルゴリズム ラムダ、関数オブジェクト、および制限された機能を示すために使用します。AMP の C++ コードのアルゴリズムを次に示します。同じ長さの 2 つの 1 次元配列が作成されます。整数の対応する要素が追加および第 3 の 1 次元配列に格納します。C++ のストレージ ・ システムが使用されていません。
void CpuMethod() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
for (int idx = 0; idx < 5; idx++)
{
sumCPP[idx] = aCPP[idx] + bCPP[idx];
}
for (int idx = 0; idx < 5; idx++)
{
std::cout << sumCPP[idx] << "\n";
}
}
ラムダ式
ラムダ式を使用して C++ のストレージ ・ システムを使用して、コードを書き換えるには、最も直接的な方法です。
void AddArraysWithLambda() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
array_view<const int, 1> a(5, aCPP);
array_view<const int, 1> b(5, bCPP);
array_view<int, 1> sum(5, sumCPP);
sum.discard_data();
parallel_for_each(
sum.extent,
[=](index<1> idx) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
}
);
for (int i = 0; i < 5; i++) {
std::cout << sum[i] << "\n";
}
}
ラムダ式のインデックスの 1 つのパラメーターを含める必要がありますしてありますrestrict(amp)。この例では、 array_viewsumオブジェクトが、1 位のランク。したがって、ステートメント ラムダのパラメーターには、 インデックスランク 1 を持つオブジェクト。実行時に、ラムダ式との各要素に対して実行される、 array_view オブジェクト。詳細については、「ラムダ式の構文」を参照してください。
Function オブジェクト
アクセラレータのコードは、関数オブジェクトに分割できます。
class AdditionFunctionObject
{
public:
AdditionFunctionObject(const array_view<int, 1>& a,
const array_view<int, 1>& b,
const array_view<int, 1>& sum
)
: a(a), b(b), sum(sum)
{
}
void operator()(index<1> idx) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
}
private:
array_view<int, 1> a;
array_view<int, 1> b;
array_view<int, 1> sum;
};
void AddArraysWithFunctionObject() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
array_view<const int, 1> a(5, aCPP);
array_view<const int, 1> b(5, bCPP);
array_view<int, 1> sum(5, sumCPP);
sum.discard_data();
parallel_for_each(
sum.extent,
AdditionFunctionObject(a, b, sum)
);
for (int i = 0; i < 5; i++) {
std::cout << sum[i] << "\n";
}
}
関数オブジェクトはコンス トラクターを含める必要があり、関数呼び出し演算子のオーバー ロードがあります。関数呼び出し演算子は 1 つのインデックス パラメーターを含める必要があります。関数オブジェクトのインスタンスが 2 番目の引数として渡されます、 parallel_for_each メソッド。この例では、次の 3 つ array_view オブジェクトは、関数オブジェクトのコンス トラクターに渡されます。Array_view オブジェクトsum 1 のランクがあります。そのため、関数呼び出し演算子パラメーターです、 インデックスランク 1 を持つオブジェクト。実行時に、関数との各要素に対して実行される、 array_view オブジェクト。詳細については、「関数呼び出し (C++)」および「関数オブジェクト」を参照してください。
C++ 関数のストレージ ・ システムの制限
アクセラレータのコードは制限された関数を作成し、ラムダ式または関数のオブジェクトからの呼び出しによってさらに分割できます。次のコード例は、ラムダ式から制限されている関数を呼び出す方法を示します。
void AddElementsWithRestrictedFunction(index<1> idx, array_view<int, 1> sum, array_view<int, 1> a, array_view<int, 1> b) restrict(amp)
{
sum[idx] = a[idx] + b[idx];
}
void AddArraysWithFunction() {
int aCPP[] = {1, 2, 3, 4, 5};
int bCPP[] = {6, 7, 8, 9, 10};
int sumCPP[5];
array_view<int, 1> a(5, aCPP);
array_view<int, 1> b(5, bCPP);
array_view<int, 1> sum(5, sumCPP);
sum.discard_data();
parallel_for_each(
sum.extent,
[=](index<1> idx) restrict(amp)
{
AddElements(idx, sum, a, b);
}
);
for (int i = 0; i < 5; i++) {
std::cout << sum[i] << "\n";
}
}
制限付きの関数を含める必要がありますrestrict(amp)と記載されている制限に従う制限の句 (C++ AMP)。