Ich habe versucht, mein eigenes Mergesort zu implementieren, basierend auf von unten nach oben/iterativer mergesort Algorithmus. Dieser Algorithmus teilt die Daten nach 2 Elementen und sortiert sie. Dann um 4 Elemente und sortiert und so weiter, bis alle Daten sortiert sind. Also, mein Plan ist jedem Thread durch 2 Elemente zuzuordnen. So mache ich das:Mergesort CUDA
__global__ void mergeBU(int *d_a, int *d_aux, int sz, int N)
{
int idk = blockIdx.x*blockDim.x+threadIdx.x;
int lo = 2 * sz * idk;
int mid = lo + sz - 1;
float hi = fminf(lo + sz + sz - 1, N - 1);
merge(d_a, d_aux, lo, mid, hi);
}
__device__ void merge(int *d_a, int *d_aux, int lo, int mid, float hi)
{
int i = lo;
int j = mid + 1;
for (int k = lo; k <= hi; k++)
{
d_aux[k] = d_a[k];
}
for (int k = lo; k <= hi; k++)
{
if (i > mid) { d_a[k] = d_aux[j]; j++; }
else if (j > hi) { d_a[k] = d_aux[i]; i++; }
else if (d_aux[j] < d_aux[i]) { d_a[k] = d_aux[j]; j++; }
else { d_a[k] = d_aux[i]; i++; }
}
}
Sagen wir, ich meine Kernel aufrufen < < < 2,4 >>> (die 8 Threads ist), so kann ich nur Art 16 Elemente max. Wenn ich 32 Elemente eingabe, bleiben die restlichen Datenindexe unberührt (16-31). Wie kann der Thread-Index weiterhin den Rest des Datenindex verarbeiten? Mit fortfahren meine ich, dass der Thread-Index (0,1,2,3,4,5,6,7) den Rest des Datenindex weiter verarbeitet, er sollte wie threadindex (dataindex, dataindex) sein -> 0 (16, 17); 1 (18,19); 2 (20,21); und so weiter. Jeder Kommentar ist willkommen.
Mein schlechter Herr, was ich gemeint ist, wird Arraydaten durch zwei Elemente auf dem ersten Iteration gespaltet, so dass die Unter Arrays enthält zwei Elemente jeweils, dann jeden Sub-Array sortierten, dann nach 4 Elementen dann sortierten und so weiter. Ich habe meine Frage bearbeitet. Ihr Rat scheint gut zu sein, aber der Thread hat einen Index, wie man jeden Thread einem Array von Daten-Indexen zuordnet, mit denen ich es zu tun habe. Da der Thread begrenzt ist, sind meine Daten auch begrenzt, wenn ich eine feste Anzahl von Elementen pro Thread habe. –
@PriyanggaJanmantaraAnusasana - verwenden Sie eine Array-Größe von 2048 als Beispiel. In meiner Version, die 8 Threads verwendet, führt jeder Thread eine Merge-Sortierung nach 256 Elementen durch, wobei jeweils 8 Durchläufe ausgeführt werden, wobei jeder Durchlauf Läufe der Größe 2, 4, 8, 16, 32, 64, 128, 256 erzeugt Läufe der Größe 256, um 4 Läufe der Größe 512 zu erstellen. Dann führen 2 Läufe Paare von Läufen der Größe 512 zusammen, um 2 Läufe der Größe 1024 zu erstellen. Dann führt 1 Thread die letzten zwei Läufe zu einem Lauf der Größe 2048 zusammen. – rcgldr
@ PriyanggaJanmantaraAnusasana - Fortsetzung, was Sie vorschlagen, ist 1024 Threads laufen zu lassen, um Läufe der Größe 2 zu erstellen, dann 512 Threads, um Läufe der Größe 4 zu erstellen, 256 Threads, um Läufe der Größe 8 zu erzeugen, ... und so weiter. Die Threads würden in sequenziellen Blöcken laufen, vielleicht 8 oder 16 Threads gleichzeitig laufen, aber wie ich in meiner Antwort erwähnte, ist die Speicherbandbreite auf einem typischen PC bei ungefähr 8 Threads erreicht. – rcgldr