Экономьте время, необходимое для cudaHostAlloc

Я пытаюсь выяснить, имеет ли смысл копировать данные в закрепленную память перед их передачей на устройство, поскольку я не имею никакого влияния на распределение моих входных данных (это библиотека).

std::vector<int> idata(WORK_SIZE);
int *idata_aligned = NULL;
int *d1 = NULL;
int *d2 = NULL;

for (int i = 0; i < WORK_SIZE; ++i)
    idata[i] = i;
CUDA_CHECK_RETURN(cudaMalloc((void**) &d1, sizeof(int) * WORK_SIZE));
CUDA_CHECK_RETURN(cudaMalloc((void**) &d2, sizeof(int) * WORK_SIZE));

printf("unpinned:\n");
{
    boost::timer::auto_cpu_timer t;
    CUDA_CHECK_RETURN(cudaMemcpy(d1, &idata[0], sizeof(int) * WORK_SIZE, cudaMemcpyHostToDevice));
}

printf("copy to pinned:\n");
{
    boost::timer::auto_cpu_timer t;
    CUDA_CHECK_RETURN(cudaHostAlloc((void**) &idata_aligned, sizeof(int) * WORK_SIZE,cudaHostAllocDefault));
    memcpy(idata_aligned, &idata[0], sizeof(int) * WORK_SIZE);
    CUDA_CHECK_RETURN(cudaMemcpy(d2, idata_aligned, sizeof(int) * WORK_SIZE, cudaMemcpyHostToDevice));
}

Вывод для 10 000 000 элементов:

unpinned:
 0.018919s wall, 0.020000s user + 0.000000s system = 0.020000s CPU (105.7%)
copy to pinned:
 0.045428s wall, 0.020000s user + 0.020000s system = 0.040000s CPU (88.1%)

Основная проблема, по-видимому, заключается в cudaHostAlloc (даже без memcpy второй подход намного медленнее).

Я сделал что-то неправильно? Есть ли другой способ использовать закрепленную память для уже выделенной памяти?


person Hannes    schedule 04.01.2013    source источник


Ответы (1)


Прирост скорости при использовании закрепленной памяти также зависит от размера передачи и вашей системы. Вы можете сначала запустить пример CudaBandwidthTest, чтобы увидеть, действительно ли он имеет смысл.

В противном случае я бы измерил определенные части вашей программы, чтобы увидеть, где теряется время. (аллок, memcpy, pcie-передача)

В зависимости от размера памяти, которую вы выделяете для блокировки страниц, также может случиться так, что вашей системе потребуется подкачать какую-то другую память на диск, увеличивая время выполнения.

В любом случае, время, которое вы показываете, довольно короткое, поэтому я думаю, что размеры передачи тоже невелики. Вы также должны иметь возможность увеличить скорость, объединив несколько небольших операций записи с более крупной.

person rico    schedule 04.01.2013
comment
CudaMemcpy почти в два раза быстрее с закрепленной памятью в моей системе, memcpy занимает около 0,010 с в случае выше. Это система без свопа (но 24 гб ОЗУ). Я также пробовал с большим количеством элементов: 100 000 000 занимает почти в 10 раз больше времени в обоих случаях; Думаю, 640 МБ должно хватить. - person Hannes; 04.01.2013
comment
Когда в CUDA была добавлена ​​закрепленная память, производительность передачи увеличилась примерно в 2 раза. С Nehalem (Intel i7) и другими процессорами, которые интегрируют контроллер памяти, пропускная способность передачи примерно одинакова, поэтому основное преимущество закрепленной памяти заключается в том, что она может участвовать в асинхронных memcpy и может быть отображена в адресное пространство CUDA и доступна. непосредственно ядрами. - person ArchaeaSoftware; 05.01.2013