я написал тест, чтобы проиллюстрировать мою проблему, код попытке скопировать 16 байт на память ни один-4-байт-выровнены, но Dest автоматически изменяетсяCUDA копия памяти сила выровнен
#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();
}
Отладка кода в VS2013, как на изображении, целевая память 0x40A8000 , но на самом деле она копирует в 0x40A8000 .
Проблема заключается в Dest будет изменен автоматически, если оно не совпадает с 4 байта. И он модифицирован молча, я потратил несколько часов, чтобы найти эту ошибку.
Я знаю, что лучше использовать хорошо выровненную память, но я пишу какую-то программу декомпрессии rar, распаковываю несколько байтов, а затем конкатбайты некоторых байтов, ее нельзя всегда выровнять.
У меня есть функция uint64 в функции типа Copy256. Является ли это обычное поведение тем, что память выровнена по силе? Любые скомпилированные флаги, которые могут отключить эту функцию? Или я должен копировать байты один за другим?
Окружающая среда: CUDA 6.5, Win7-32bit, VS2013
Когда я запускаю ваш пример кода, я получаю ошибку незаконной записи в ядре Copy128 из-за нерационального доступа к памяти, что и должно произойти. Я не понимаю, что вы пытаетесь сделать здесь – talonmies
За исключением процессоров x86, все обращения к памяти на графическом процессоре должны быть естественно выровнены, то есть выровнены по размеру доступа, например. 4-байтовый доступ должен быть выровнен с 4-байтной границей. Таким образом, на графических процессорах это выравнивание для доступа к памяти необходимо для * функциональной корректности *, а не только для производительности, как на x86. Это упоминается в документации CUDA. Для несогласованных копий вам не нужно копировать более крупные объекты побайтно, просто используйте узкие обращения для конечных случаев и используйте большие копии для большей части передачи. – njuffa