Если у меня есть concurrency::array_view
оперированы в concurrency::parallel_for_each
цикл, я понимаю, что я могу продолжать другие задачи на процессоре во время выполнения цикла:
using namespace Concurrency;
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// do some intense computations on av
}
// do some stuff on the CPU while we wait
av.synchronize(); // wait for the parallel_for_each loop to finish and copy the data
Но что, если я хочу не ждать для параллели для цикла, но начать копировать данные обратно из графического процессора так скоро, как возможно. Будет ли следующая работа?
using namespace Concurrency;
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// do some intense computations on av
}
// I know that we won't be waiting to synch when I call this, but will we be waiting here
// until the data is available on the GPU end to START copying?
completion_future waitOnThis = av.synchronize_asynch();
// will this line execute before parallel_for_each has finished processing, or only once it
// has finished processing an the data from "av" has started copying back?
completion_future.wait();
Я читал об этой теме на Мотылек, но после прочтения следующего я не очень мудрый:
Обратите внимание, что parallel_for_each выполняется как будто синхронно
вызывающий код, но в действительности он асинхронный. То есть однажды
Выполнен параллельный вызов_я_для и ядро передано
во время выполнения область some_code_B продолжает выполняться немедленно
поток процессора, в то время как параллельно ядро исполняется графическим процессором
потоки. Однако, если вы попытаетесь получить доступ к данным (array или array_view)
что вы захватили в лямбду в области some_code_B, ваш код
будет блокироваться, пока результаты не станут доступными. Отсюда и правильный
утверждение: parallel_for_each как будто синхронно с точки зрения
видимые побочные эффекты, но асинхронные в реальности.
Мне не нравится, как это было объяснено. Лучший способ думать об этом — то, что parallel_for_each
очереди работают на GPU, поэтому он возвращается практически сразу. Существует множество способов, которыми ваш код на стороне ЦП может блокироваться, пока работа в очереди не будет завершена, например, явный вызов synchronize
или доступ к данным из одного из array_view
экземпляры, используемые в parallel_for_each
using namespace concurrency;
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// Queue (or schedule if you like) some intense computations on av
}
Хост-код может выполняться сейчас. Расчеты AMP могут начаться или не начаться. Если код здесь доступ av
затем он будет блокироваться, пока работа над графическим процессором не будет завершена и данные в av
был записан и может быть синхронизирован с памятью хоста.
Это будущее, так что это также запланированная задача. Это не гарантируется
выполнить в любой конкретный момент. Если это запланировано, то оно заблокирует поток, на котором работает av
правильно синхронизирован с памятью хоста (как указано выше).
completion_future waitOnThis = av.synchronize_asynch();
Больше кода хоста можно выполнить здесь. Если доступ к коду хоста av
затем он будет блокироваться до parallel_for_each
завершено (как указано выше). В какой-то момент среда выполнения выполнит будущее и заблокирует до av
синхронизировался с памятью хоста. Если он доступен для записи и был изменен, он будет скопирован обратно в память хоста.
completion_future.wait();
Призыв к wait
будет заблокирован, пока будущее не завершено (до вызова wait
нет никакой гарантии, что что-либо действительно выполнено). На этом этапе вы гарантировано, что вычисления GPU завершены и что av
можно получить доступ к процессору.
Сказав все это, добавив waitOnThis
Кажется, что будущее более сложное.
array_view<int> av;
parallel_for_each(extent<1>(number),[=](index<1> idx)
{
// do some intense computations on av on the GPU
}
// do some independent CPU computation here.
av.synchronize();
// do some computation on the CPU that relies on av here.
Документы MSDN не очень хороши в этой теме. Следующие Сообщение блога лучше. В том же блоге есть несколько других сообщений об асинхронных API.
Других решений пока нет …