2013-11-07 6 views
1

Если у меня есть concurrency::array_view эксплуатируется на в concurrency::parallel_for_each цикле, я понимаю, что я могу продолжать другие задачи на CPU в то время как цикл выполняется:будет array_view.synchronize_asynch ждать завершения 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 

Но что, если я хочу, чтобы не ждать для параллельного цикла, но начните копирование данных с GPU как можно скорее. Будет ли следующая работа?

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(); 

Я читал эту тему на The Moth, но после прочтения следующего я на самом деле не любая мудрее:

Пожалуйста, обратите внимание, что parallel_for_each выполняется, как если синхронны код вызова, но в действительности, он асинхронен. То есть как только выполняется вызов parallel_for_each , и ядро ​​было передано во время выполнения , область some_code_B продолжает немедленно выполнять поток ЦП, а параллельно ядро ​​выполняется потоками GPU . Однако, если вы попытаетесь получить доступ к данным (array или array_view) , которые вы захватили в lambda в регионе some_code_B, ваш код будет блокироваться до тех пор, пока результаты не станут доступными. Следовательно, правильный оператор : parallel_for_each как-то синхронно с точки зрения видимых побочных эффектов, но в асинхронном режиме.

ответ

2

Мне не нравится, как это объясняется. Лучший способ подумать об этом - то, что очереди parallel_for_each работают на GPU, поэтому он возвращается почти сразу. Есть много способов, что ваш CPU-код на стороне может блокировать, пока очередь работа не будет завершена, например, явно призывая 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, он будет блокироваться до завершения работы на GPU и данные в av были записаны и могут быть синхронизированы с памятью хоста.

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

completion_future waitOnThis = av.synchronize_asynch(); 

Дополнительный код может выполняться здесь. Если код хоста обращается к av, он будет блокироваться до завершения parallel_for_each (как указано выше). В какой-то момент время исполнения будет исполнять будущее и блокироваться до тех пор, пока av не синхронизируется с памятью хоста. Если он доступен для записи и был изменен, он будет скопирован обратно в память хоста.

completion_future.wait(); 

Вызов wait будет блокироваться, пока будущее не завершено (до вызова wait нет никакой гарантии, что что-то на самом деле выполняется).На этом этапе вам гарантировано, что расчеты графического процессора завершены и что 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 не очень хороши в этой теме. Лучше всего следующее: blog post. Есть несколько других сообщений в асинхронных API в одном блоге.

+0

Спасибо, это было полезно. Поэтому просто для подтверждения: 'array_view :: synchronize_async()' ничего не будет блокировать сам по себе, он будет только проинструктировать базовые данные, которые будут переданы *, когда все, что работает над ним, закончилось, да? – arman

+0

Да, (документ MSDN довольно разрежен на этом). Вы можете думать об этом как о очередности операции копирования для array_view, так как в какой-то момент это будет выполнено. –

+0

Хорошо, спасибо за разъяснение! – arman

Смежные вопросы