Проблема с производительностью C++ AMP — резкое непостоянство производительности без какого-либо перемещения данных

У меня есть алгоритм, который опирается на ок. 15 различных представлений array_view и 8 различных вызовов ядра AMP for_each. Природа алгоритма заключается в том, что все данные копируются в GPU, а затем набор вызовов ядра выполняется снова и снова, пока не будет достигнут некоторый порог. Примечание. Я еще не реализовал пороговую логику, которая потребовала бы возврата данных обратно в ЦП.

Полный набор вызовов ядра называется циклом. В промежутках между каждым циклом я не ссылаюсь ни на какие данные array_view на ЦП.... таким образом, я не ожидаю никакого перемещения данных обратно в ЦП. Однако выполнение циклов не является регулярным. Большую часть времени циклы занимают 10 или около того миллисекунд, но затем каждый 3-й или 4-й цикл (или иногда подряд) цикл занимает 400 или 500 миллисекунд для выполнения. Внутренняя логика вызовов ядра всегда в основном одинакова ..... поэтому увеличение времени выполнения не связано с логикой графического процессора.

Что может быть причиной резкого увеличения времени для некоторых циклов? См. примеры таймингов ниже.

Время завершения первого цикла 503,278 (мс) Это время включает накладные расходы на инициализацию AMP, компиляцию ядра и перемещение данных в графический процессор.

Время выполнения еще 1 цикла: 11,3105 (мс) Время выполнения еще 2 циклов: 10,7455 (мс) Время выполнения еще 3 циклов: 538,668 (мс) Время выполнения еще 4 циклов: 13,3055 (мс) Время выполнения еще 5 циклов : 14,4544 (мс) Время выполнения еще 6 циклов: 12,353 (мс) Время выполнения еще 7 циклов: 17,5154 (мс) Время выполнения еще 8 циклов: 755,255 (мс) Время выполнения еще 9 циклов: 11,7461 (мс) Время на выполнение еще 10 циклов: 14,6612 (мс) Время на выполнение еще 11 циклов: 417,788 (мс) Время на выполнение еще 12 циклов: 399,167 (мс) Время на выполнение еще 13 циклов: 12,2898 (мс) Время на выполнение еще 14 циклов: 16,9694 (мс) Время выполнения еще 15 циклов: 151,228 (мс) Время выполнения еще 16 циклов: 404,659 (мс) Время выполнения еще 17 циклов: 10,4977 (мс) Время выполнения еще 18 циклов: 15,7178 (мс) Время до завершение еще 19 циклов: 207,768 (мс) Время выполнения еще 20 циклов: 511,538 (мс) Время выполнения еще 21 цикла: 14,4339 (мс) Время выполнения еще 22 циклов: 252,77 (мс) Время выполнения еще 23 циклов: 504,565 (мс) Время выполнения еще 24 циклов: 12,6931 (мс) Время выполнения еще 25 циклов: 15,5403 (мс) Время выполнения еще 26 циклов: 303,68 (мс) Время выполнения еще 27 циклов : 440,331 (мс) Время выполнения еще 28 циклов: 8,63698 (мс) Время выполнения еще 29 циклов: 13,9312 (мс) Время выполнения еще 30 циклов: 755,637 (мс) Выход..... Нажмите любую клавишу, чтобы продолжить . . .


person Mark S    schedule 05.12.2013    source источник
comment
Не могли бы вы поделиться (хотя бы псевдокодом), как вы измеряете время, обратите внимание, что у команды C++ AMP есть сообщение в блоге по теме: Как измерить производительность алгоритмов C++ AMP?. Также интересны производитель и модель используемого вами графического процессора, а также предназначен ли этот блок для вычислений или есть что-то еще, работающее в фоновом режиме, которое может его использовать.   -  person Lukasz Mendakiewicz    schedule 06.12.2013
comment
Видеокарта - AMD Radeon HD 6130. Что касается подхода к выбору времени... Я использую тот же метод, что и в книге C++ AMP. См. следующий пример кода: for (i=1; i‹=500; i++) { QueryPerformanceCounter(&start); //выполнить 500 циклов и сравнить производительность AMPFuncs(myView, parms, avDirects, avPatterns, avErrors, avActuals); QueryPerformanceCounter(&end); std::wcout ‹‹ Время завершения ‹‹ i ‹‹ больше циклов: ‹‹ ElapsedTime(start, end) ‹‹ (мс) ‹‹ std::endl; }   -  person Mark S    schedule 06.12.2013
comment
Использование только 50% выделенной памяти графического процессора, а графический процессор используется как для моих вычислений, так и для дисплея ноутбука, хотя я ничего активно не делаю на дисплее во время выполнения вычислений.   -  person Mark S    schedule 06.12.2013
comment
Как вы синхронизируете ЦП и ГП в AMPFuncs — используете ли вы accelerator_view::wait() при каждом вызове? Кроме того, мы наблюдали, как AMD выполняла довольно агрессивное степпинг мощности даже на настольных системах, что, как я ожидаю, будет преувеличено на ноутбуке — в этой степени вы можете попробовать настроить параметры питания Windows или, возможно, некоторые параметры в Catalyst Control Center. . Сказав, что ~ 50-кратные прыжки кажутся мне слишком крутыми, чтобы их можно было объяснить этим.   -  person Lukasz Mendakiewicz    schedule 06.12.2013
comment
Набросок исходного кода (и некоторое переформатирование вашего вопроса) действительно поможет здесь. Я не хочу читать ваш код счетчика производительности, но я не вижу в вашем комментарии flush() или wait(), поэтому возможно, что вы на самом деле не синхронизируете каждый вызов отдельно. Помните, что выполнение ядра AMP на самом деле не является выполнением, оно ставится в очередь. См. stackoverflow.com/questions/19830470/ для получения более подробной информации о времени и очереди.   -  person Ade Miller    schedule 06.12.2013
comment
Я работаю в немедленном режиме и вызываю view.wait() после каждого вызова ядра. Я обновил свой драйвер и просматриваю параметры Catalyst Center. Я дам вам знать, если я что-нибудь найду.   -  person Mark S    schedule 07.12.2013