2013-03-31 3 views
0

Использование паролей для перекрытия передачи данных с использованием ядра не работает в моей системе.CUDA Overlap Data не работает

Здравствуйте, Я хочу использовать Пересечение вычислений и передачу данных в CUDA, но я не могу. Справочный документ NVIDIA говорит, что при использовании потоков можно использовать перерасчет вычислений и передачу данных. но моя система не работает Пожалуйста, помогите мне.

Моя система находится ниже

  • ОС: Window 7 64bit
  • CUDA: версия 5.0.7
  • Develp комплект: Визуальная Студийского 2008
  • GPU: GTX 680

Я получаю профиль Посмотреть вот так enter image description here

я не получаю перекрытием, код ниже:

-new pinned memory 
     cudaHostAlloc((void **)&apBuffer, sizeof(BYTE)*lBufferSize,cudaHostAllocDefault); 
    -call function 

    //Input Data 
    for(int i=0;i<m_n3DChannelCnt*m_nBucket;++i) 
    { 
     cudaErrorChk_Return(cudaMemcpyAsync(d_ppbImg[i],ppbImg[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyHostToDevice,m_pStream[i/m_nBucket])); 
    } 
    //Call Function 
    for(int i=0;i<m_n3DChannelCnt ;++i) 
    {KernelGetVis8uObjPhsPhs<<<nBlockCnt,nThreadCnt,0,m_pStream[i]>>>(d_ppbVis[i],d_ppbAvg[i],d_ppfPhs[i],d_ppfObj[i],d_ppbAmp[i] 
              ,nTotalSize,d_ppstRefData[i],d_ppbImg[i*m_nBucket],d_ppbImg[i*m_nBucket+1],d_ppbImg[i*m_nBucket+2],d_ppbImg[i*m_nBucket+3] 
              ,fSclFloatVis2ByteVis); 

    } 
    //OutputData 
    for(int i=0;i<m_n3DChannelCnt;++i) 
    { 
     if(ppbVis && ppbVis[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbVis[i],d_ppbVis[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
     if(ppbAvg && ppbAvg[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAvg[i],d_ppbAvg[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
     if(ppfPhs && ppfPhs[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfPhs[i],d_ppfPhs[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
     if(ppfObj && ppfObj[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfObj[i],d_ppfObj[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
     if(ppbAmp && ppbAmp[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAmp[i],d_ppbAmp[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 

    } 

Пожалуйста, дайте мне знать о том, почему профилировщик не показывает совмещение выполнения ядра и передачи данных.

+0

Обратите внимание на форматирование и язык, который вы используете в вопросах переполнения стека, __much__. Когда вы разместили его, это был почти непонятный беспорядок. – talonmies

ответ

1

Вам необходимо вызвать cudaMemcpyAsync(), а ядро ​​запускается в правильном порядке. Перед возможностью вычисления 3.5 существовала только одна очередь для вызова операций на стороне устройства, и они не переупорядочиваются. Объединение «Вызов функции» и фазы «OutputData» к чему-то вроде

//Call Function and OutputData 
for(int i=0;i<m_n3DChannelCnt ;++i) 
{KernelGetVis8uObjPhsPhs<<<nBlockCnt,nThreadCnt,0,m_pStream[i]>>>(d_ppbVis[i],d_ppbAvg[i],d_ppfPhs[i],d_ppfObj[i],d_ppbAmp[i] 
             ,nTotalSize,d_ppstRefData[i],d_ppbImg[i*m_nBucket],d_ppbImg[i*m_nBucket+1],d_ppbImg[i*m_nBucket+2],d_ppbImg[i*m_nBucket+3] 
             ,fSclFloatVis2ByteVis); 

    if(ppbVis && ppbVis[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbVis[i],d_ppbVis[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
    if(ppbAvg && ppbAvg[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAvg[i],d_ppbAvg[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
    if(ppfPhs && ppfPhs[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfPhs[i],d_ppfPhs[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
    if(ppfObj && ppfObj[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppfObj[i],d_ppfObj[i],sizeof(float)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 
    if(ppbAmp && ppbAmp[i]) cudaErrorChk_Return(cudaMemcpyAsync(ppbAmp[i],d_ppbAmp[i],sizeof(BYTE)*m_nImgWidth*m_nImgHeight,cudaMemcpyDeviceToHost,m_pStream[i])); 

} 

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

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

0

Возможно, вам захочется проверить, работает ли ваш код в ожидании (т. Е. С перекрытием) в LINUX. Я только что понес эту проблему и обнаружил, что WINDOWS может иметь некоторые проблемы (либо в драйвере NVIDIA, либо в самой Windows), что мешает перекрытию в потоке CUDA.

Вы можете попробовать проверить, работает ли пример simpleStreams в SDK с перекрытием на вашем компьютере. Для моего случая, «simpleStream», работающий в Windows, не имеет перекрытия вообще, но он отлично работает в Linux. Чтобы быть конкретным, я использую CUDA 5.0 + VS2010, на Fermi GTX570.

-1

TL; DR: Проблема вызвана TDR опции задержки WDDM в Nsight Monitor! Если установлено значение false, появится проблема. Вместо этого, если вы установите значение задержки TDR на очень высокое число, а опция «enabled» равна true, проблема исчезнет.

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

Я только недавно смог в основном решить эту проблему! Он специфичен для окон и aero Я думаю. Попробуйте эти шаги и опубликуйте свои результаты, чтобы помочь другим! Я попробовал его на GTX 650 и GT 640.

Перед тем, как сделать что-нибудь, подумайте using both onboard gpu(as display) and the discrete gpu (for computations), потому что аттестованы проблемы с драйвером NVidia для окон! Когда вы используете встроенный gpu, указанные драйверы не загружаются полностью, так много ошибок уклоняются. Кроме того, во время работы поддерживается работоспособность системы!

  1. Убедитесь, что ваша проблема параллельности не связана с другими проблемами, такими как старые драйвера (вкл. Версии BIOS), неправильный код, неспособного устройства и т.д.
  2. Перейти к компьютеру> свойства
  3. Выберите расширенные настройки системы на левой стороне
  4. Перейдите на вкладку Advanced
  5. на установках выберите Производительность
  6. на вкладке Визуальные эффекты, выберите «а для лучшей производительности ".

Это отключит аэро и почти все визуальные эффекты. Если эта конфигурация работает, вы можете попытаться включить по очереди ящики для визуальных эффектов, пока не найдете точный, который вызывает проблемы!

В качестве альтернативы, вы можете:

  1. правой кнопкой мыши на рабочем столе, выберите персонализировать
  2. Выберите тему из основных тем, что не имеет аэро.

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

Пожалуйста, когда вы попробуете эти решения, вернитесь сюда и опубликуйте свои выводы!

Для меня это решить проблему для большинства случаев (плиточный DGEMM я сделал), но учтите, что я до сих пор не может работать «simpleStreams» правильно и достичь параллельности .. .

UPDATE: проблема заключается в том полностью решен с новым окном установкой !! Предыдущие шаги улучшили поведение для некоторых случаев, но новая версия решила все проблемы!

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