CUDA Закрепленная память для маленьких данных - PullRequest
2 голосов
/ 04 августа 2011

Я запускаю тесты пропускной способности хост-устройства для разных размеров данных, и заметил увеличение пропускной способности, когда память хоста закреплена за возможностью просмотра страниц.Ниже приведен график зависимости пропускной способности в МБ / с от размера передачи данных в байтах.Можно заметить, что для небольшого количества данных (<300 КБ) плата за просмотр лучше, чем при закреплении ... это связано с распределением памяти в O / S?Эта программа тестирования полосы пропускания взята из примера кода NVidia sdk (с небольшими изменениями с моей стороны), и я тестирую против Tesla C2050 с использованием CUDA 4.0.O / S - это 64-битная версия Linux. </p>

enter image description here

Ответы [ 2 ]

1 голос
/ 04 августа 2011

Реализация cudaMemcpy имеет разные пути кода для разных устройств, местоположений источника и назначения и размеров данных, чтобы попытаться достичь максимально возможной пропускной способности.

Различные скорости, которые вы видите, вероятно, связаны с переключением реализации при изменении размера массива.

Например, графические процессоры Fermi имеют как выделенные механизмы копирования (которые могут работать параллельно с ядрами, работающими на SM), так и SM, которые могут получать доступ к памяти хоста через PCI-e. Для небольших массивов может быть более эффективно реализовать cudaMemcpy как ядро, работающее на SM, которое непосредственно считывает память хоста и сохраняет загруженные данные в память устройства (или наоборот), поэтому драйвер может сделать это. Или может быть более эффективно использовать механизм копирования - я не уверен, что он делает на практике, но я думаю, что переключение между ними является причиной кроссовера, который вы видите на графике.

0 голосов
/ 04 августа 2011

Возможно, что тест обманывает.

Вот один из временных кодов:

cutilSafeCall( cudaEventRecord( start, 0 ) );
if( PINNED == memMode )
{
    for( unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++ )
    {
        cutilSafeCall( cudaMemcpyAsync( h_odata, d_idata, memSize,
                                cudaMemcpyDeviceToHost, 0) );
    }
}
else
{
    for( unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++ )
    {
        cutilSafeCall( cudaMemcpy( h_odata, d_idata, memSize,
                                cudaMemcpyDeviceToHost) );
    }
}
cutilSafeCall( cudaEventRecord( stop, 0 ) );

Обратите внимание, что тест использует разные функции для создания MemCPY для разных типов памяти.Я думаю, это обман, потому что основное различие между режимами заключается в том, как распределяется память, с cudaHostAlloc для закрепленного и с malloc для закрепленного.

Различные функции Memcpy могут иметь различные пути проверки ошибок и настройки передачи.

Итак, попробуйте изменить тест и выполнить копирование в обоих режимах с помощью cudaMemcpy(), например, изменив все ifs после cudeEventRecord(...) на if( 0 && (PINNED == memMode) )

...