CUDA Schub-und sort_by_key
Ich bin auf der Suche nach einem Sortier-Algorithmus auf CUDA kann sortiert ein array A von Elementen (Doppel) und gibt ein array von Schlüssel B für das array A.
Ich weiß, die sort_by_key
Funktion in der Schub-Bibliothek aber ich will mein array der Elemente bleiben unverändert.
Was kann ich tun?
Mein code ist:
void sortCUDA(double V[], int P[], int N) {
real_t *Vcpy = (double*) malloc(N*sizeof(double));
memcpy(Vcpy,V,N*sizeof(double));
thrust::sort_by_key(V, V + N, P);
free(Vcpy);
}
ich Vergleiche den Schub-Algorithmus gegen andere, die ich auf sequencial cpu
N mergesort sortCUDA
113 0.000008 0.000010
226 0.000018 0.000016
452 0.000036 0.000020
905 0.000061 0.000034
1810 0.000135 0.000071
3621 0.000297 0.000156
7242 0.000917 0.000338
14484 0.001421 0.000853
28968 0.003069 0.001931
57937 0.006666 0.003939
115874 0.014435 0.008025
231749 0.031059 0.016718
463499 0.067407 0.039848
926999 0.148170 0.118003
1853998 0.329005 0.260837
3707996 0.731768 0.544357
7415992 1.638445 1.073755
14831984 3.668039 2.150179
115035495 39.276560 19.812200
230070990 87.750377 39.762915
460141980 200.940501 74.605219
Schub, die Leistung ist nicht schlecht, aber ich denke, wenn ich mit OMP können wahrscheinlich einfach eine bessere CPU-Zeit
Ich denke, das ist, weil zu memcpy
LÖSUNG:
void thrustSort(double V[], int P[], int N)
{
thrust::device_vector<int> d_P(N);
thrust::device_vector<double> d_V(V, V + N);
thrust::sequence(d_P.begin(), d_P.end());
thrust::sort_by_key(d_V.begin(), d_V.end(), d_P.begin());
thrust::copy(d_P.begin(),d_P.end(),P);
}
wobei V eine meine double-Werte Sortieren
- Eine Kopie der vor dem Sortieren? Auch, wenn Sie eine Schub-Benutzer sind, möchten Sie vielleicht erwägen den Beitritt zur Schub google-Gruppe.
- Ja, das habe ich, aber die Leistung war stark reduziert
- Vielleicht sollte man post-code und beantworten Sie die Fragen über Größen. Ich würde erwarten, dass die Kosten für die Sortierung Betrieb deutlich höher sind als die Kosten für eine Vektor-Kopie.
- ich habe bearbeitet die main-post
- Wo Sie beabsichtigen, zu verwenden, OMP?
- auf meiner CPU mergesort-Algorithmus
- Es sieht für mich so aus, du bist nicht mit dem CUDA-Gerät überhaupt. Schub hat host-side algorithmen und device-side algorithmen. Auch Sie sagte, das hinzufügen der Vektor-Kopie gemacht, die es "so viel langsamer". Ich sehe aber keine Daten oder Beweise zu haben, dass Sie zeitlich die Differenz.
- nicht mit dem cuda-Gerät überhaupt? mmm, warum,, die passiert werden kann? O_o
- Sie müssen lernen, mehr über die Schub, vielleicht werfen Sie einen Blick auf die quick start guide. Vektoren können live auf dem host oder Gerät. Wenn Sie pass-Vektoren (oder Zeiger auf arrays), die host-basiert, Schub wird mit einem host-basierten Algorithmus zum Sortieren (wobei die GPU-idle). Wenn Sie pass Vektoren oder Zeiger, die Gerät-basierte, Schub verwenden Sie ein Gerät-basierten Algorithmus zum Sortieren (also auf der GPU). Dein code, den du gepostet hast gibt mir den Eindruck, dass Ihre Zeiger sind host-basiert.
- Wahr ist, habe ich nie benutzt Schub vor Dank, ich werde es Lesen, etwas mehr über Zeiger-Gerät
- Ich bin wirklich beeindruckt, Schub ist schneller als mergesort, auch für die Größen, die kleiner als 226, zumal Sie hinzufügen, die Kosten der Vektor-Kopie (weiß nicht, ob Sie dies mit Ihrem mergesort -- Sie nicht posten, dass code.) Wenn Sie die Schub-Gerät Sortieren, es werden die Kosten für die Kopie der Vektoren zu dem Gerät. Dies wird zu bestrafen Ihre kleinen Sorten, aber wahrscheinlich geben eine erhebliche Verbesserung die Größe diejenigen haben. Auch, die Entwickler-version von Schub wesentlich schneller bei Sortierung.
- Auch wenn Sie sicher sind, Sie laufen auf der GPU, da Sie noch nicht erzählte uns, was GPU und CPU Sie läuft, können wir nicht wirklich abschätzen, ob diese erwartete Leistung, oder nicht. Sie könnte ausgeführt werden, auf eine 1-SM laptop GPU und so eine große speedup nicht erwarten würde, zum Beispiel.
- In der Tat war ich mit cpu-Schub, ich habe es behoben und nun die Beschleunigung ist mehr als 20x besser als cpu-Schub-Danke, sehr viel 😀
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie ändern Vergleichsfunktion zum Sortieren von Schlüsseln anstelle von Werten. @Robert Crovella richtig darauf hingewiesen, dass ein raw-device-pointer zugeordnet werden, kann nicht vom host. Der modifizierte Algorithmus ist unten:
Und hier ist die alternative mit arrayfire. Obwohl ich nicht sicher bin, welches effizienter ist, da arrayfire Lösung verwendet zwei zusätzliche Felder:
rawA = thrust::raw_pointer_cast(devA.data());
ich konnte es nicht funktionieren. Es tut kompilieren, aber Schub löst eine Ausnahme aus, wenn Sie versuchen, Sie zu dereferenzieren rawA nach dieser Zeile. Ich war in der Lage, eine Alternative version arbeiten, verwenden im Grunde die gleiche Methode, aber cudaMemcpyToSymbol, statt der Zeile.rawA = thrust::raw_pointer_cast(devA.data());
sollte so etwas wie dieses:double * rawA = thrust::raw_pointer_cast(devA.data());
Sowieso, was du gepostet hast, jetzt nicht kompiliert bei mir (rawA ist nicht definiert in der Zeile), aber wenn ich ändern, dass es funktioniert.Wie groß ist dieses Feld? Der effizienteste Weg, was die Geschwindigkeit angeht, werden wahrscheinlich nur duplizieren Sie die original-array vor der Sortierung, wenn der Speicher verfügbar ist.
Aufbauend auf der Antwort von @asm (ich war nicht in der Lage, um es arbeiten), dieser code schien, für mich zu arbeiten, und nicht nur Sortieren der keys. Ich glaube jedoch, es beschränkt sich auf den Fall, wo die Schlüssel sind in der Reihenfolge 0, 1, 2, 3, 4 ... entsprechend der (Doppel -) Werte. Da dies ein "index-Wert" Sortieren, es kann erweitert werden auf den Fall einer beliebigen Reihenfolge von Tasten, vielleicht, indem Sie ein indiziertes kopieren. Aber ich bin nicht sicher, dass der Prozess der Generierung der index-Reihenfolge und dann die Umgestaltung des original-keys werden nicht schneller, als nur das kopieren der ursprünglichen Wert auf einen neuen Vektor (für den Fall der willkürlichen Schlüssel).