Share via


Übersicht über C++ AMP

C++ beschleunigte enorme Parallelität (C++-AMP) beschleunigt Ausführung von C++-Code, indem Daten-parallele Hardware wie eine Graphikverarbeitungseinheit (GPU) auf einer einzelnen Grafikkarte Funktionen.Mit C++-AMP verwenden, können Sie mehrdimensionale Datenalgorithmen codieren, sodass Ausführung mithilfe von Parallelität auf heterogener Hardware beschleunigt werden kann.Das C++-AMPprogrammiermodell umfasst mehrdimensionale Arrays, die Indizierung, Arbeitsspeicher-Übertragung, Tiling und eine mathematische Funktionsbibliothek.Sie können C++-AMPsprachenerweiterungen verwenden, um zu steuern, wie Daten aus der CPU zum GPU und auf die Rückseite verschoben werden, damit Sie die Leistung verbessern können.

Systemanforderungen

  • Windows 7, Windows 8, Windows Server 2008 R2 oder Windows Server 2012

  • DirectX 11-Funktions-Ebene 11,0 oder höhere Hardware

  • Für das Debuggen auf dem Software-Emulator, ist Windows 8 oder Windows Server 2012 erforderlich.Für das Debuggen auf der Hardware, müssen Sie die Treiber für die Grafikkarte installieren.Weitere Informationen finden Sie unter Debuggen von GPU-Code.

Einführung

Die beiden folgenden Beispiele veranschaulichen die Hauptbestandteile von C++-AMP.Angenommen, Sie die entsprechenden Elemente aus zwei eindimensionalen Arrays hinzufügen möchten.Beispielsweise können Sie {1, 2, 3, 4, 5} und {6, 7, 8, 9, 10} hinzufügen, um zu erhalten {7, 9, 11, 13, 15}.Ohne C++-AMP zu verwenden, schreiben Sie den folgenden Code, um die Zahlen hinzuzufügen und die Ergebnisse anzuzeigen.

#include <iostream>

void StandardMethod() {

    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";
    }
}

Wichtige Teile des Codes sind, wie folgt:

  • Daten: Die Daten bestehen aus drei Arrays.Alle haben den gleichen Rang (einen) und Länge (fünf).

  • Iteration: Die erste for-Schleife stellt einen Mechanismus zum Durchlaufen der Elemente in Arrays bereit.Der Code, den Sie ausführen möchten, um die Summen zu berechnen, wird im ersten for-Block enthalten.

  • Index: Die idx-Variable greift auf die einzelnen Elemente der Arrays zu.

Verwenden C++-AMP geschrieben haben Sie möglicherweise stattdessen den folgenden Code.

#include <amp.h>
#include <iostream>
using namespace concurrency;

const int size = 5;

void CppAmpMethod() {
    int aCPP[] = {1, 2, 3, 4, 5};
    int bCPP[] = {6, 7, 8, 9, 10};
    int sumCPP[size];
    
    // Create C++ AMP objects.
    array_view<const int, 1> a(size, aCPP);
    array_view<const int, 1> b(size, bCPP);
    array_view<int, 1> sum(size, sumCPP);
    sum.discard_data();

    parallel_for_each( 
        // Define the compute domain, which is the set of threads that are created.
        sum.extent, 
        // Define the code to run on each thread on the accelerator.
        [=](index<1> idx) restrict(amp)
    {
        sum[idx] = a[idx] + b[idx];
    }
    );

    // Print the results. The expected output is "7, 9, 11, 13, 15".
    for (int i = 0; i < size; i++) {
        std::cout << sum[i] << "\n";
    }
}

Die gleichen grundlegenden Elemente sind vorhanden, jedoch C++-AMPkonstrukte werden verwendet:

  • Daten: Sie verwenden C++-Arrays, um drei C++-AMP-array_view-Objekte zu erstellen.Sie stellen vier Werte, um ein Objekt array_view zu erstellen: die Datenwerte, Rang, der Elementtyp und die Länge des array_view-Objekts in jeder Dimension.Der Rang und der Typ werden als Typparameter übergeben.Die Daten und die Länge werden als Konstruktorparameter übergeben.In diesem Beispiel ist das C++-Array, die dem Konstruktor übergeben wird, eindimensional.Der Rang und die Länge werden verwendet, um die rechteckige Form der Daten im array_view-Objekt zu erstellen, und die Datenwerte werden verwendet, um das Array auszufüllen.Die Ablaufbibliothek enthält auch Arrayklasse ein, die eine Schnittstelle verfügt, die der array_view-Klasse ähnelt und später in diesem Artikel erläutert wird.

  • Iteration: parallel_for_each-Funktion (C++ AMP) stellt einen Mechanismus zum Durchlaufen der Datenelemente oder Berechnungsdomäne bereit.In diesem Beispiel wird die Berechnungsdomäne durch sum.extent angegeben.Der Code, den Sie ausführen möchten, wird in einem Lambda-Ausdruck oder in der Kernelfunktion enthalten.restrict(amp) gibt an, dass nur die Teilmenge der Programmiersprache C++, die C++-AMP beschleunigen kann, verwendet wird.

  • Index: Die index-Klasse-Variable, idx, wird mit einem Rang von einem deklariert, um den Rang des array_view-Objekts übereinstimmt.Mit dem Index verwenden, können Sie auf die einzelnen Elemente der array_view-Objekte zugreifen.

Strukturierungs- und Indizierungs-Daten: Index und Wertebereich

Sie müssen die Datenwerte definieren und die Form der Daten deklarieren, bevor Sie den Kernelcode ausführen können.Alle Daten werden definiert, um ein Array zu rechteckig sein (), und Sie können das Array definieren, um einen Rang (Anzahl der Dimensionen) verfügen.Die Daten können eine beliebige Größe in jedem der Dimensionen sein.

Hh265136.collapse_all(de-de,VS.110).gifIndex Klasse

index-Klasse gibt einen Speicherort im array oder array_view-Objekt an, indem es den Offset vom Ursprung in jeder Dimension in ein - Objekt kapselt.Wenn Sie auf eine Stelle im Array zugreifen, übergeben Sie ein - Objekt index zum Indizierungsoperator, [], anstelle einer Liste von ganzzahligen Indizes.Sie können auf die Elemente in jeder Dimension zugreifen, indem Sie array::operator()-Operator oder array_view::operator()-Operator verwenden.

Das folgende Beispiel erstellt einen eindimensionalen Index, der das dritte Element in einem eindimensionalen array_view-Objekt angibt.Der Index wird verwendet, um das dritte Element im array_view-Objekt auszugeben.Die Ausgabe lautet 3.

    
int aCPP[] = {1, 2, 3, 4, 5};
array_view<int, 1> a(5, aCPP);
index<1> idx(2);
std::cout << a[idx] << "\n";  
// Output: 3

Im folgenden Beispiel wird ein zweidimensionalen Index, der das Element im die Zeile = 1 und die Spalte = 2 in einem zweidimensionalen array_view-Objekt angibt.Der erste Parameter im Konstruktor index ist die Zeilenkomponente, und der zweite Parameter ist die Spaltenkomponente.Die Ausgabe lautet 6.

int aCPP[] = {1, 2, 3,
              4, 5, 6};
array_view<int, 2> a(2, 3, aCPP);
index<2> idx(1, 2);
std::cout << a[idx] << "\n";
// Output: 6

Das folgende Beispiel erstellt einen dreidimensionalen Index, der das Element im die Tiefe = 0, = 1 die Zeile und Spalte = 3 in einem dreidimensionalen array_view-Objekt angibt.Der - Parameter ist die erste Tiefenkomponente, besteht der zweite Parameter die Zeilenkomponente, und der dritte Parameter ist die Spaltenkomponente.Die Ausgabe lautet 8.

int aCPP[] = {
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

array_view<int, 3> a(2, 3, 4, aCPP); 
// Specifies the element at 3, 1, 0.
index<3> idx(0, 1, 3);               
std::cout << a[idx] << "\n";

// Output: 8

Hh265136.collapse_all(de-de,VS.110).gifWertebereich Klasse

extent-Klasse (C++ AMP) gibt die Länge der Daten in jeder Dimension des array oder array_view-Objekts an.Sie können einen Wertebereich erstellen und ihn verwenden, um ein array oder array_view-Objekt zu erstellen.Sie können den Umfang von vorhandenen array oder einem array_view-Objekt auch abrufen.Im folgenden Beispiel gibt die Länge des Wertebereichs in jeder Dimension eines array_view-Objekts.

int aCPP[] = {
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// There are 3 rows and 4 columns, and the depth is two.
array_view<int, 3> a(2, 3, 4, aCPP); 
std::cout << "The number of columns is " << a.extent[2] << "\n";
std::cout << "The number of rows is " << a.extent[1] << "\n";
std::cout << "The depth is " << a.extent[0]<< "\n";
std::cout << "Length in most significant dimension is " << a.extent[0] << "\n";

Im folgenden Beispiel wird ein array_view-Objekt, das die gleichen Dimensionen wie das - Objekt im vorherigen Beispiel hat, verwendet jedoch dieses Beispiels ein - Objekt extent, anstatt, explizite Parameter im array_view-Konstruktor verwenden.

int aCPP[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
extent<3> e(2, 3, 4);
array_view<int, 3> a(e, aCPP);
std::cout << "The number of columns is " << a.extent[2] << "\n";
std::cout << "The number of rows is " << a.extent[1] << "\n";
std::cout << "The depth is " << a.extent[0] << "\n";

Verschieben von Daten in die Zugriffstaste: Array und array_view

Zwei Datencontainer, die verwendet werden, um Daten auf die Zugriffstaste zu verschieben, werden in der Ablaufbibliothek definiert.Sie sind Arrayklasse und array_view-Klasse.Die - Klasse ist eine Containerklasse array, die eine Tiefenkopie der Daten erstellt, wenn das Objekt erstellt wird.Die - Klasse array_view ist eine Wrapperklasse, die die Daten kopiert, wenn die Kernelfunktion auf die Daten zugegriffen wird.Wenn die Daten auf dem Quellgerät erforderlich sind, sind die kopierte Daten zurück.

Hh265136.collapse_all(de-de,VS.110).gif- Array

Wenn ein array-Objekt erstellt wird, wird eine Tiefenkopie der Daten auf der Zugriffstaste erstellt, wenn Sie einen Konstruktor verwenden, der einen Zeiger auf das Dataset enthält.Die Kernelfunktion ändert die Kopie auf der Zugriffstaste.Wenn die Ausführung der Kernelfunktion beendet wird, müssen Sie die Daten in der Quelldatenstruktur kopieren.Im folgenden Beispiel multipliziert jedes Element in einem Vektor durch 10.Nachdem die Kernelfunktion beendet wurde, wird Vektorkonvertierungsoperator verwendet, um die Daten zurück in das Vektorobjekt zu kopieren.

std::vector<int> data(5);
for (int count = 0; count < 5; count++) 
{
     data[count] = count;
}

array<int, 1> a(5, data.begin(), data.end());

parallel_for_each(
    a.extent, 
    [=, &a](index<1> idx) restrict(amp)
    {
        a[idx] = a[idx] * 10;
    }
);

data = a;
for (int i = 0; i < 5; i++) 
{
    std::cout << data[i] << "\n";
}

Hh265136.collapse_all(de-de,VS.110).gifarray_view-Klasse

array_view hat fast dieselben Member wie die array-Klasse, aber das zugrunde liegende Verhalten ist nicht dasselbe.Die Daten, die dem array_view-Konstruktor übergeben werden, werden nicht auf dem GPU repliziert, während es mit einem array-Konstruktor ist.Stattdessen werden die Daten in der Zugriffstaste kopiert, wenn die Kernelfunktion ausgeführt wird.Wenn Sie zwei array_view-Objekte erstellen, die die gleichen Daten verwenden, verweisen array_view beide Objekte denselben Speicherbereich an.Wenn Sie dies durchführen, müssen Sie jeden Multithreadzugriff synchronisieren.Der Hauptvorteil der Anwendung der array_view-Klasse besteht darin, dass Daten verschoben werden nur, wenn es erforderlich ist.

Hh265136.collapse_all(de-de,VS.110).gifVergleich von Arrays und des array_view

In der folgenden Tabelle werden die Ähnlichkeiten und Unterschiede zwischen array und den array_view-Klassen zusammengefasst.

Beschreibung

Array-Klasse

array_view-Klasse

Wenn Rang bestimmt wird

Zur Kompilierzeit.

Zur Kompilierzeit.

Wenn Wertebereich bestimmt wird

Zur Laufzeit.

Zur Laufzeit.

Form

Rechteckig.

Rechteckig.

Datenspeicherung

Der ist ein Datencontainer.

Der ist ein Datenwrapper.

Kopieren

Explizit und Tiefenkopie an der Definition.

Implizite Kopie, wenn auf sie durch die Kernelfunktion zugegriffen wird.

Datenabruf

Mithilfe der Arraydaten zurück in ein - Objekt für die CPU kopieren, dennoch Sie.

Durch Direktzugriff array_view wenden Sie ein oder, indem Sie array_view::synchronize-Methode aufrufen, um den Zugriff auf die Daten auf dem ursprünglichen Container fortzusetzen.

Ausführen von Code zu Daten: parallel_for_each

Die parallel_for_each-Funktion definiert den Code, den Sie auf die Zugriffstaste für die Daten im array oder array_view-Objekt ausführen möchten.Betrachten Sie folgenden Code aus der Einführung dieses Themas.

#include <amp.h>
#include <iostream>
using namespace concurrency;

void AddArrays() {
    int aCPP[] = {1, 2, 3, 4, 5};
    int bCPP[] = {6, 7, 8, 9, 10};
    int sumCPP[5] = {0, 0, 0, 0, 0};

    array_view<int, 1> a(5, aCPP);
    array_view<int, 1> b(5, bCPP);
    array_view<int, 1> sum(5, sumCPP);

    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";
    }
}

Die parallel_for_each-Methode akzeptiert zwei Argumente, eine Berechnungsdomäne und einen Lambda-Ausdruck.

Die Berechnungsdomäne ist ein extenttiled_extent-Objekt oder ein - Objekt, das den Satz von Threads definiert, um für die parallele Ausführung zu erstellen.Ein Thread wird für jedes Element in der Berechnungsdomäne generiert.In diesem Fall ist das Objekt extent eindimensional und verfügt über fünf Elemente.Daher werden fünf Threads gestartet.

Der Lambda-Ausdruck definiert den Code, um auf jeden Thread ausgeführt werden.Die Erfassungsklausel, [=] angibt, ist, dass der Text des Lambda-Ausdrucks auf alle aufgezeichneten Variablen nach Wert zugreift, die in diesem Fall a, b, und sum.In diesem Beispiel wird die Parameterliste einer eindimensionalen index-Variable, die idx genannt wird.Der Wert idx[0] ist 0 im ersten Thread und nimmt um einen in jedem folgenden Thread zu.restrict(amp) gibt an, dass nur die Teilmenge der Programmiersprache C++, die C++-AMP beschleunigen kann, verwendet wird.Die Einschränkungen auf Funktionen, die den Einschränkensmodifizierer ist, werden in Einschränkungs-Klausel (C++-AMP) beschrieben.Weitere Informationen finden Sie unter Lambda-Ausdruckssyntax.

Der Lambda-Ausdruck kann den Code enthalten, um auszuführen, oder er kann eine separate Kernelfunktion aufrufen.Die Kernelfunktion muss den restrict(amp)-Modifizierer enthalten.Das folgende Beispiel entspricht dem vorherigen Beispiel, aber es wird eine separate Kernelfunktion auf.

#include <amp.h>
#include <iostream>
using namespace concurrency;

void AddElements(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] = {0, 0, 0, 0, 0};

    array_view<int, 1> a(5, aCPP);
    array_view<int, 1> b(5, bCPP);
    array_view<int, 1> sum(5, sumCPP);

    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";
    }
}

Beschleunigender Code: Kacheln und Barrieren

Sie können zusätzliche Beschleunigung erhalten, indem Sie Tiling verwenden.Kacheln teilt die Threads in gleiche rechteckige Teilmengen oder Kacheln.Sie bestimmen die entsprechende Kachelgröße auf Grundlage das Dataset und der Algorithmus, dass Sie codieren.Für jeden Thread haben Sie Zugriff auf den globalen Position eines Datenelements relativ zum gesamten array oder array_view und den Zugriff auf den lokalen Speicherort relativ zur Kachel.Verwenden des Indexwerts der lokalen Variablen den Code vereinfacht, da Sie den Code schreiben müssen, um Indexwerte von globalen auf die lokale Variable zu übersetzen.So Tiling verwenden, extent::tile-Methode auf der Berechnungsdomäne in der parallel_for_each-Methode aufgerufen werden, und ein tiled_index-Objekt im Lambda-Ausdruck verwenden.

In typischen Anwendungen werden die Elemente in einer Kachel auf irgendeine Weise verknüpft, und der Code muss auf Werte über der Kachel zugreifen und nachverfolgen.Verwenden Sie das - Schlüsselwort tile_static Schlüsselwort und tile_barrier::wait-Methode, um dies zu erreichen.Eine Variable, die das tile_static-Schlüsselwort, hat einen Bereich in einer ganzen Kachel und eine Instanz der Variablen wird erstellt für jede Kachel.Sie müssen die Synchronisierung des KachelThreadzugriffs der Variablen behandeln.tile_barrier::wait-Methode beendet die Ausführung des aktuellen Threads, bis alle Threads in der Kachel den Aufruf tile_barrier::wait erreicht haben.So können Sie Werte über der Kachel zusammenfassen, indem Sie tile_static-Variablen verwenden.Anschließend können Sie alle Berechnungen beenden, die Zugriff auf alle Werte erfordern.

Das folgende Diagramm stellt ein zweidimensionales Array Samplingdaten dar, die in den Kacheln angeordnet wird.

Indexwerte in einer gekachelten Erweiterung

Im folgenden Codebeispiel wird die Samplingdaten aus dem vorherigen Diagramm.Der Code ersetzt jeden Wert in der Kachel durch den Durchschnitt der Werte in der Kachel.

// Sample data:
int sampledata[] = {
    2, 2, 9, 7, 1, 4,
    4, 4, 8, 8, 3, 4,
    1, 5, 1, 2, 5, 2,
    6, 8, 3, 2, 7, 2};

// The tiles:
// 2 2    9 7    1 4
// 4 4    8 8    3 4
//
// 1 5    1 2    5 2
// 6 8    3 2    7 2

// Averages:
int averagedata[] = { 
    0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 
};

array_view<int, 2> sample(4, 6, sampledata);
array_view<int, 2> average(4, 6, averagedata);

parallel_for_each(
    // Create threads for sample.extent and divide the extent into 2 x 2 tiles.
    sample.extent.tile<2,2>(),
    [=](tiled_index<2,2> idx) restrict(amp)
    {
        // Create a 2 x 2 array to hold the values in this tile.
        tile_static int nums[2][2];
        // Copy the values for the tile into the 2 x 2 array.
        nums[idx.local[1]][idx.local[0]] = sample[idx.global];
        // When all the threads have executed and the 2 x 2 array is complete, find the average.
        idx.barrier.wait();
        int sum = nums[0][0] + nums[0][1] + nums[1][0] + nums[1][1];
        // Copy the average into the array_view.
        average[idx.global] = sum / 4;
      }
);

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 6; j++) {
        std::cout << average(i,j) << " ";
    }
    std::cout << "\n";
}

// Output:
// 3 3 8 8 3 3
// 3 3 8 8 3 3
// 5 5 2 2 4 4
// 5 5 2 2 4 4

Mathematische Bibliotheken

C++-AMP umfasst zwei mathematischen Bibliotheken.Die Bibliothek mit doppelter Genauigkeit in Concurrency::precise_math-Namespace bietet Unterstützung für Funktionen mit doppelter Genauigkeit.Sie unterstützt auch Genauigkeitsfunktionen, obwohl die Unterstützung mit doppelter Genauigkeit auf der Hardware noch benötigt wird.Es stimmt mit Spezifikation C99 (ISO/IEC 9899) dem überein.Die Zugriffstaste muss vollständige doppelte Genauigkeit unterstützen.Sie können bestimmen, ob sie bewirkt, indem Sie den Wert accelerator::supports_double_precision-Datenmember überprüfen.Die schnelle mathematische Bibliothek, in Concurrency::fast_math-Namespace, enthält einen anderen Satz mathematischer Funktionen.Diese Funktionen, die nur float Operanden unterstützen, führen aus schneller, aber sind nicht so genau wie in der mathematischen Bibliothek mit doppelter Genauigkeit.Die Funktionen werden in der <amp_math.h> Headerdatei enthalten und alle werden mit restrict(amp) deklariert.Die Funktionen in der <cmath> Headerdatei werden in fast_math und in precise_math-Namespaces importiert.Das restrict-Schlüsselwort wird verwendet, um die <cmath> Version und die C++-AMPversion zu unterscheiden. Der folgende Code berechnet den Logarithmus zur Basis 10, mithilfe der schnellen Methode, jedes Werts, der in der Berechnungsdomäne ist.

#include <amp.h>
#include <amp_math.h>
#include <iostream>
using namespace concurrency;


void MathExample() {

    double numbers[] = { 1.0, 10.0, 60.0, 100.0, 600.0, 1000.0 };
    array_view<double, 1> logs(6, numbers);

    parallel_for_each(
        logs.extent,
         [=] (index<1> idx) restrict(amp) {
            logs[idx] = concurrency::fast_math::log10(logs[idx]);
        }
    );

    for (int i = 0; i < 6; i++) {
        std::cout << logs[i] << "\n";
    }
}

Grafik-Bibliothek

C++-AMP umfasst eine Graphikbibliothek, die für die beschleunigte Grafikprogrammierung entworfen wurde.Diese Bibliothek ist nur auf Geräten verwendet, die systemeigene Grafikfunktionen von unterstützen.Die Methoden sind in Concurrency::graphics-Namespace und werden in der <amp_graphics.h> Headerdatei enthalten.Die Hauptkomponenten der Graphikbibliothek sind:

  • texture-Klasse: Sie können die Texturklasse verwenden, um Texturen aus dem Arbeitsspeicher oder aus einer Datei zu erstellen.Texturen ähneln Arrays, da sie Daten enthalten, und sie ähneln Containern in der Standardvorlagenbibliothek (STL) in Bezug auf Zuweisungs- und Kopienkonstruktion.Weitere Informationen finden Sie unter STL Containers.Die Vorlagenparameter für die texture-Klasse sind der Elementtyp und der Rang.Der Rang kann 1, 2 oder 3.Der Elementtyp kann einer der kurzen Vektortypen sein, die weiter unten in diesem Artikel beschrieben werden.

  • writeonly_texture_view-Klasse: Bietet lesegeschützten Zugriff auf jede Textur.

  • Kurze Vektor-Bibliothek: Definiert einen Satz kurze Vektortypen der Länge 2, 3 und 4, die auf Grundlage int, uint, float, double, Norm oder unorm sind.

Windows Store-App

Wie andere C++-Bibliotheken können Sie C++-AMP in den Windows Store-App verwenden.Diese Artikel wird beschrieben, wie C++-AMPcode in den App enthält, der erstellt wird, indem C++, C#, Visual Basic oder JavaScript verwendet:

C++-AMP und -Parallelitätsschnellansicht

Die Parallelitätsschnellansicht bietet Unterstützung für das Analysieren der Leistung von C++-AMPcodes ein.Diese Elemente beschreiben diese Funktionen:

Leistungs-Empfehlungen

Modulo und Division ganzer Zahlen ohne Vorzeichen erheblich bessere Leistung als Modulo und Division von Zahlen mit Vorzeichen.Es wird empfohlen, dass Sie ganze Zahlen ohne Vorzeichen verwenden, wenn möglich.

Siehe auch

Referenz

Lambda-Ausdruckssyntax

Weitere Ressourcen

C++ AMP (C++ Accelerated Massive Parallelism)

Referenz (C++ AMP)

Parallele Programmierung im Blog von systemeigenem Code