Существует ли специальная функция «ожидания события», которая может одновременно ожидать 3 очереди на стороне устройства, чтобы она не ждала все очереди последовательно со стороны хоста?
Существует ли команда контрольной точки для отправки в очередь команд, так что она должна ждать, пока другие очереди команд не достигнут того же (вертикального) барьера/контрольной точки, чтобы ждать и продолжать работу со стороны устройства, поэтому не требуется обходной путь на стороне хоста?
На данный момент я попробовал две разные версии:
clWaitForEvents(3, evt_);
а также
int evtStatus0 = 0;
clGetEventInfo(evt_[0], CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(cl_int), &evtStatus0, NULL);
while (evtStatus0 > 0)
{
clGetEventInfo(evt_[0], CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(cl_int), &evtStatus0, NULL);
Sleep(0);
}
int evtStatus1 = 0;
clGetEventInfo(evt_[1], CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(cl_int), &evtStatus1, NULL);
while (evtStatus1 > 0)
{
clGetEventInfo(evt_[1], CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(cl_int), &evtStatus1, NULL);
Sleep(0);
}
int evtStatus2 = 0;
clGetEventInfo(evt_[2], CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(cl_int), &evtStatus2, NULL);
while (evtStatus2 > 0)
{
clGetEventInfo(evt_[2], CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(cl_int), &evtStatus2, NULL);
Sleep(0);
}
второй немного быстрее (я видел это у кого-то другого), и оба выполняются после 3 команд сброса.
Глядя на результаты профилировщика CodeXL, первый из них дольше ждет между точками финиша, а некоторые операции даже не кажутся перекрывающимися. Второй показывает, что 3 точки завершения находятся в пределах 3 миллисекунд, поэтому он быстрее, и более длинные части перекрываются (чтение + запись + вычисление одновременно).
Если есть способ добиться этого с помощью только одной команды ожидания со стороны хоста, должна быть и ее версия «flush», но я не смог найти.
Есть ли способ получить изображение ниже вместо добавления сбросов между каждым этапом конвейера?
queue1 write checkpoint write checkpoint write
queue2 - compute checkpoint compute checkpoint compute
queue3 - checkpoint read checkpoint read
все контрольные точки должны быть вертикально синхронизированы, и все эти действия не должны начинаться, пока не будет дан сигнал. Такие как:
queue1.ndwrite(...);
queue1.ndcheckpoint(...);
queue1.ndwrite(...);
queue1.ndcheckpoint(...);
queue1.ndwrite(...);
queue2.ndrangekernel(...);
queue2.ndcheckpoint(...);
queue2.ndrangekernel(...);
queue2.ndcheckpoint(...);
queue2.ndrangekernel(...);
queue3.ndread(...);
queue3.ndcheckpoint(...);
queue3.ndread(...);
queue3.ndcheckpoint(...);
queue3.ndread(...);
queue1.flush()
queue2.flush()
queue3.flush()
queue1.finish()
queue2.finish()
queue3.finish()
все контрольные точки обрабатываются на стороне устройства, и со стороны хоста требуется только 3 команды завершения (даже лучше, только 1 завершение для всех очередей?)
Как привязать 3 очереди к 3 событиям с помощью "clWaitForEvents(3, evt_);" на данный момент это:
hCommandQueue->commandQueue.enqueueBarrierWithWaitList(NULL, &evt[0]);
hCommandQueue2->commandQueue.enqueueBarrierWithWaitList(NULL, &evt[1]);
hCommandQueue3->commandQueue.enqueueBarrierWithWaitList(NULL, &evt[2]);
если этот «барьер очереди» может общаться с другими очередями, как я могу этого добиться? Нужно ли поддерживать события на стороне хоста, пока все очереди не будут завершены, или я могу удалить их или повторно использовать позже? Из документации кажется, что событие первого барьера может быть помещено во вторую очередь, а событие второго барьера может быть помещено в третье вместе с событием первого, поэтому, возможно, это похоже на:
hCommandQueue->commandQueue.enqueueBarrierWithWaitList(NULL, &evt[0]);
hCommandQueue2->commandQueue.enqueueBarrierWithWaitList(evt_0, &evt[1]);
hCommandQueue3->commandQueue.enqueueBarrierWithWaitList(evt_0_and_1, &evt[2]);
in the end wait for only evt[2] maybe or using only 1 same event for all:
hCommandQueue->commandQueue.enqueueBarrierWithWaitList(sameEvt, &evt[0]);
hCommandQueue2->commandQueue.enqueueBarrierWithWaitList(sameEvt, &evt[1]);
hCommandQueue3->commandQueue.enqueueBarrierWithWaitList(sameEvt, &evt[2]);
where to get sameEvt object?
кто-нибудь пробовал это? Должен ли я запускать все очереди с барьером, чтобы они не запускались до тех пор, пока я не вызову какое-либо событие со стороны хоста, или ленивые выполнения «enqueue» на 100% можно доверять «не запускать, пока я не сброслю / не закончу» их? Как передать событие от хоста к устройству (у того же самогоEvt нет функции «повышения», это clCreateUserEvent?)?
Все 3 очереди расположены по порядку и находятся в одном контексте. Нестандартный тип поддерживается не всеми видеокартами. Используются привязки C++.
Также есть enqueueWaitList (это устарело?) и clEnqueueMarker, но я не знаю, как их использовать, и в документации нет примера на веб-сайте Khronos.