Also man programmiert am schnellsten in Brook+, die hartgesottenen Optimierer können auch IL nehmen.
Das Prinzip ist ganz einfach.
Es gibt 2 Dateien, in einer Datei ist der Kernel Code, dieser wird auf der GPU ausgeführt.
In der 2. Datei ist dein Programm, was auf der CPU läuft.
Die erste Datei wird von Brook geparsed, um dann gültigen C++ Code zu erzeugen. Das heißt, Brook+ ist eigentlich nur zur Compilerzeit wichtig, danach wird alles über die CAL Schnittstelle abgewickelt.
Aber jetzt beginn ich erst mal Schritt für Schritt:
1. SDK donwloaden und alles installieren.
2. (optional) Syntax Highlighting in Visual C++ installieren (siehe Brook+ installing guide Kapitel 5)
3. Benutzerdefinierte Buildregel erstellen:
Visual C++ starten und irgendein Projekt öffnen, dann links im Prjektmappenexplorer auf das Projekt Rechtsklicken und dann auf Benutzerdefinierte Buildregeln... dann Neue Regeldatei da dann Name Dateinam und Verzeichnis auswählen (praktisch egal) und dann Buildregel hinzufügen...
Das ist jetzt der Brook+ Parser:
Einstellungen:
Anzeigennamen egal
Ausführungsbeschreibung egal
Ausgaben $(InputName).cpp
Befehlszeile "<Brook+Pfad>\sdk\bin\brcc_d.exe" -o $(InputName) $(InputName).br
Dateierweiterung *.br
Name irgendwas
Rest so wie er ist
Dann Die Regel und die Datei speichern und den Haken dranmachen, nun ist ein Brok-Compiler, oder wie du es genannt hast verfügbar.
4.) Dieser Schritt muss für jedes Projekt gemacht werden.
Unter Projekt -> Eingenschaften -> Konfigurationseigenschaften -> Linker -> Zusätzliche Abhängigkeiten muss die amdcalcl.lib und amdrt.lib aus <cal-verzeichnis>\lib\xp32\ drinstehen, sonst bekommt man unaufgelöste symbole.
Jetzt zum richtigen Programmieren.
Ich mach jetzt ein Beispielprogramm, was dann analog für (praktisch) alle Programme gilt.
gpu.br
Code:
kernel void add(float a<>,float b<>, out float c<>)
{
c=a+b;
}
test.cpp
Code:
#include <iostream>
#include <gpu.h>//Diese Datei wird von Brook+ erstellt und enthält all die kernel
using namespace std;
int main()
{
unsingned int Dim1[]={1};//Damit kann man die Größen der Dimensionen festlegen also 1 Dimensional mit Größe 1
brook::stream<float>sa(1,Dim1);//dadurch mach ich ein Stream auf der Grafikkarte
brook::stream<float>sb(1,Dim1);
brook::stream<float>sc(1,Dim1);
float aa[1],ab[1],ac[1];/das sind die Arrays, die die Grafikkartendaten entsprechen wrden/sollen
aa[0]=123;
ab[0]=456;
sa.read(aa);//Dadurch werden mit DMA die Dateien auf die Grafikkarte kopiert
sb.read(ab);
add(sa,sb,sc);//Das führt den Kernel aus wie eine einfache Funktion
sc.write(ac);
cout<<ac[0];
system("PAUSE");
return 0;
}
Das wahrs schon, addiert 123 und 456 auf der Grafikkarte uns gibt es über die CPU aus.
Edit: Möglicherweise muss man noch die GPU.cpp zum Projekt hinzufügen (wird bei jedem kompilieren erstellt)