ich einen Test geschrieben, mein Problem zu veranschaulichen, versuchen Sie den Code 16 Bytes zu einem keine-4-Byte-ausgerichteten Speicher zu kopieren, aber die dest wird automatischcuda Speicherkopie Kraft ausgerichtet
#include <cuda.h>
#include <cuda_runtime.h>
#include <stdio.h>
__global__
void Copy128(char *dest,const char *src)
{
((int*)dest)[0]=((int*)src)[0];
((int*)dest)[1]=((int*)src)[1];
((int*)dest)[2]=((int*)src)[2];
((int*)dest)[3]=((int*)src)[3];
}
__global__
void fill_src(char *src)
{
for(int i=0; i<16; i++)
src[i] = i+1; // starts from 1
}
int main()
{
char* dest;
cudaMalloc(&dest, 17);
char* src;
cudaMalloc(&src, 16);
fill_src<<<1, 1>>>((char*)src); // fill some value for debugging
// copy to dest+1 which is not aligned to 4
Copy128<<<1, 1>>>(dest + 1, src);
getchar();
}
modifizierte Debuggen den Code in VS2013 wie im Bild, ist der Zielspeicher 0x40A8000 , aber eigentlich ist es Kopien 0x40A8000 .
Das Problem ist die dest würde automatisch geändert werden, wenn es nicht auf 4-Byte ausgerichtet ist. Und es wurde still modifiziert, ich verbrachte Stunden damit, diesen Fehler zu finden.
Ich weiß, es ist am besten, gut ausgerichteten Speicher zu verwenden, aber ich schreibe einige Rar-Dekomprimierungsprogramm, dekomprimiere einige Bytes und dann einige Bytes concat, es kann nicht immer ausgerichtet werden.
Ich glaube, ich würde uint64 in Funktion wie Copy256 verwenden. Ist das normale Verhalten, dass der Speicher kraftorientiert ist? Irgendwelche kompilierenden Flags, die diese Funktionalität ausschalten können? Oder sollte ich Bytes nacheinander kopieren?
Umwelt: CUDA 6.5, Win7-32bit, VS2013
Wenn ich Ihren Beispielcode zum ausführen ich einen illegalen Schreibfehler im Copy128 Kernel erhalten, weil des nicht ausgerichteten Speicherzugriff, das ist genau das, was geschehen soll. Ich verstehe nicht, welchen Punkt Sie hier zu machen versuchen – talonmies
Anders als auf x86-CPUs müssen alle Speicherzugriffe auf eine GPU natürlich ausgerichtet sein, das heißt, auf die Größe des Zugriffs, z. Der 4-Byte-Zugriff muss auf eine 4-Byte-Grenze ausgerichtet sein. Auf GPUs ist diese Ausrichtung für Speicherzugriffe für * funktionale Korrektheit * erforderlich, nicht nur für die Leistung wie bei x86. Dies wird in der CUDA-Dokumentation erwähnt. Bei fehlausgerichteten Kopien müssen Sie größere Objekte nicht Byte für Byte kopieren, sondern nur die schmalen Zugriffe für die Endfälle verwenden und für den Großteil der Übertragung breite Kopien verwenden. – njuffa