Cuda virtuelle Klasse

Ich möchte einige virtuelle Methoden in einem cuda-Kernel ausführen, aber anstatt das Objekt im selben Kernel zu erstellen, möchte ich es auf dem Host erstellen und in den GPU-Speicher kopieren.

Ich erstelle erfolgreich Objekte in einem Kernel und rufe eine virtuelle Methode auf. Das Problem tritt beim Kopieren des Objekts auf. Dies ist sinnvoll, da der virtuelle Funktionszeiger offensichtlich falsch ist. Was passiert ist einfach "Cuda Grid Start fehlgeschlagen", zumindest ist dies, was Nsight sagt. Aber wenn man sich den SASS ansieht, stürzt er bei der Dereferenzierung des virtuellen Funktionszeigers ab, was Sinn macht.

Ich benutze natürlich Cuda 4.2 und kompiliere mit "compute_30" auf einer passenden Karte.

Also, was ist der empfohlene Weg zu gehen? Oder wird diese Funktion einfach nicht unterstützt?

Ich hatte die Idee, zuerst einen anderen Kernel auszuführen, der Dummy-Objekte erstellt und den virtuellen Funktionszeiger extrahiert, um meine Objekte vor dem Kopieren zu "patchen". Leider funktioniert dies nicht wirklich (ich habe es noch nicht herausgefunden) und es wäre auch eine hässliche Lösung.

P.S. Dies ist eigentlich eine Wiederholung vondiese Frage, die leider nie vollständig beantwortet wurde.

Bearbeiten:

Also fand ich einen Weg, um das zu tun, was ich wollte. Aber nur um klar zu sein: Dies ist überhaupt keine Antwort oder Lösung, die Antwort wurde bereits gegeben, dies ist nur ein Hack, nur zum Spaß.

Schauen wir uns also zuerst an, was Cuda beim Aufrufen einer virtuellen Methode tut. Unten ist das Debuggen von SASS

//R0 is the address of our object
LD.CG R0, [R0];  
IADD R0, R0, 0x4;  
NOP;  
MOV R0, R0;  
LD.CG R0, [R0];
...
IADD R0, RZ, R9;  
MOV R0, R0;  
LDC R0, c[0x2][R0];
...
BRX R0 - 0x5478

Unter der Annahme, dass "c [0x2] [INDEX]" für alle Kernel konstant ist, können wir den Index für eine Klasse erhalten, indem wir einfach einen Kernel ausführen und dies tun, wobei obj ein neu erstelltes Objekt der Klasse ist, die Folgendes betrachtet:

unsigned int index = *(unsigned int*)(*(unsigned int*)obj + 4);

Dann benutze so etwas:

struct entry
{
    unsigned int vfptr;// := &vfref, thats our value to store in an object
    int dummy;// := 1234, great for debugging
    unsigned int vfref;// := &dummy
    unsigned int index;
    char ClassName[256];//use it as a key for a dict
};

Speichern Sie dies sowohl auf dem Host als auch im Gerätespeicher (die Speicherorte sind Gerätespeicher). Auf dem Host können Sie den Klassennamen als Nachschlagewerk für ein zu "patchendes" Objekt verwenden.

Aber nochmal: Ich würde das nicht ernst nehmen, weil die Leistung der virtuellen Funktionen überhaupt nicht gut ist.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage