Verwenden von Lambdas, Function-Objekten und eingeschränkten Funktionen
Der C++-AMP-Code, den Sie auf der Zugriffstaste ausführen möchten, wird als Argument in einem Aufruf der parallel_for_each
Methode angegeben. Als Argument können Sie einen Lambda-Ausdruck oder ein Funktionsobjekt (Funktionselement) verwenden. Zudem kann mit dem Lambdaausdruck oder dem Funktionsobjekt eine eingeschränkte C++ AMP-Funktion aufgerufen werden. In diesem Thema werden Lambdas, Funktionsobjekte und eingeschränkte Funktionen anhand eines Algorithmus zum Hinzufügen von Arrays veranschaulicht. Im folgenden Beispiel ist der Algorithmus ohne C++ AMP-Code dargestellt. Es werden zwei eindimensionale Arrays derselben Länge erstellt. Die entsprechenden ganzzahligen Elemente werden hinzugefügt und in einem dritten eindimensionalen Array gespeichert. C++ AMP wird nicht verwendet.
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";
}
}
Lambdaausdruck
Das Verwenden eines Lambda-Ausdrucks ist die einfachste Möglichkeit, den Code mit C++ AMP umzuschreiben.
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";
}
}
Der Lambdaausdruck muss einen Indizierungsparameter und restrict(amp)
enthalten. Im Beispiel hat das array_view-Objektsum
den Rang 1. Daher ist der Parameter für die Lambda-Anweisung ein Indexobjekt mit Rang 1. Zur Laufzeit wird der Lambda-Ausdruck für jedes Element im array_view-Objekt einmal ausgeführt. Weitere Informationen finden Sie unter Lambda-Ausdruckssyntax.
Function-Objekt
Sie können den Code des Beschleunigers in ein Funktionsobjekt zerlegen.
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";
}
}
Das Funktionsobjekt muss einen Konstruktor und eine Überladung des Funktionsaufrufoperators enthalten. Im Funktionsaufrufoperator muss ein Indizierungsparameter enthalten sein. Eine Instanz des Funktionsobjekts wird als zweites Argument an die parallel_for_each-Methode übergeben. In diesem Beispiel werden drei array_view Objekte an den Funktionsobjektkonstruktor übergeben. Das array_view-Objekt sum
hat den Rang 1. Daher ist der Parameter für den Funktionsaufrufoperator ein Indexobjekt mit Rang 1. Zur Laufzeit wird die Funktion einmal für jedes Element im array_view-Objekt ausgeführt. Weitere Informationen finden Sie unter Funktionsaufruf und Funktionsobjekte in der C++-Standardbibliothek.
Eingeschränkte C++ AMP-Funktion
Sie können den Code des Beschleunigers weiter zerlegen, indem Sie eine eingeschränkte Funktion erstellen und diese mit einem Lambda-Ausdruck oder einem Funktionsobjekt aufrufen. Im folgenden Codebeispiel wird veranschaulicht, wie eine eingeschränkte Funktion mit einem Lambda-Ausdruck aufgerufen wird.
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)
{
AddElementsWithRestrictedFunction(idx, sum, a, b);
});
for (int i = 0; i <5; i++) {
std::cout <<sum[i] <<"\n";
}
}
Die eingeschränkte Funktion muss die Einschränkungen enthalten restrict(amp)
und einhalten, die in restrict (C++ AMP) beschrieben werden.
Siehe auch
C++ AMP (C++ Accelerated Massive Parallelism)
Lambdaausdruckssyntax
Funktionsaufruf
Funktionsobjekte in der C++-Standardbibliothek
restrict (C++ AMP)