Когда не требуется вызов «synchronize ()» в C ++ AMP? - PullRequest
3 голосов
/ 22 сентября 2011

Справочная информация: Обзор AMP на C ++ см. В недавнем выступлении Даниэля Мота .

. Проходя начальные обходы здесь , здесь , здесь и здесь .

Только в этом последнем обращении они делают вызов array_view.synchronize().

В этих простыхпримеры, не нужен ли вызов synchronize()?Когда это безопасно исключить?Можем ли мы полагать, что parallel_for_each будет вести себя «синхронно» без него (с исходным кодом)?

Ответы [ 4 ]

10 голосов
/ 24 сентября 2011

Используйте synchronize (), когда вы хотите получить доступ к данным без , проходящего через интерфейс array_view. Если весь ваш доступ к данным использует операторы и функции array_view, вам не нужно использовать synchronize (). Как упоминал Даниэль, деструктор array_view также вызывает синхронизацию, и в этом случае лучше вызывать synchronize (), чтобы вы могли получить любые исключения, которые могут быть выброшены.

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

Это кажется очевидным из названия, но я упоминаю об этом, потому что другие операции array_view также могут вызывать синхронизацию. C ++ AMP array_view старается сделать так, чтобы копирование между процессором и памятью GPU оказало влияние - любая операция, которая читает данные через интерфейс представления массива, также приведет к копированию.

std::vector<int> v(10);
array_view<int, 1> av(10, v);
parallel_for_each(av.grid, [=](index<1> i) restrict(direct3d) {
   av[i] = 7;
}
// at this point, data isn't copied back
std::wcout << v[0]; // should print 0

// using the array_view to access data will force a copy
std::wcout << av[0]; // should print 7

// at this point data is copied back
std::wcout << v[0]; // should print 7
4 голосов
/ 24 сентября 2011

my_array_view_instance.synchronize не требуется для простых примеров, которые я показал, потому что вызовы деструктора синхронизируются.Сказав это, я не следую наилучшей практике (извините), которая заключается в явном вызове синхронизации.Причина в том, что если в этот момент будут сгенерированы какие-либо исключения, вы не заметите их, если оставите их деструктору, поэтому, пожалуйста, вызовите синхронизацию явно.

Cheers

Daniel

3 голосов
/ 26 сентября 2011

Только что заметил, что второй вопрос в вашем посте о параллельности параллельного_для_синхронизации и асинхронного (извините, я привык к одному вопросу на тему ;-) "Можем ли мы доверять параллельному_для_обращения вести себя" синхронно "без него (w / r / tисходящий код)? "

Ответ на этот вопрос есть в моем посте о parallel_for_each: http://www.danielmoth.com/Blog/parallelforeach-From-Amph-Part-1.aspx

.., а также в записи BUILD, на которую вы указали в период с 29: 20-33: 00http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-802T

Короче говоря, нет, вы не можете поверить, что это синхронно, это асинхронно.Точка синхронизации (неявная или явная) - это любой код, который пытается получить доступ к данным, которые, как ожидается, будут скопированы обратно из графического процессора в результате вашего параллельного цикла.

Cheers

Daniel

1 голос
/ 22 сентября 2011

Держу пари, что исключить это никогда не безопасно, потому что в многопоточном (параллельном или параллельном) предположении ничего не безопасно. Существуют определенные гарантии, которые дают вам определенные конструкции, но вы должны быть очень осторожными и дотошными, чтобы не нарушать эти гарантии, вводя что-то, что, на ваш взгляд, хорошо, но когда на самом деле в основе всего лежит сложность.

Еще не проводил время с C ++ - AMP, но я склонен попробовать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...