Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Требования к барьеру для неупорядоченного представления доступа (UAV)
Барьеры UAV в Direct3D 12
В Direct3D 12 смежные запуски шейдеров вычислений в одном списке команд могут выполняться параллельно на GPU, если они не синхронизированы с промежуточным барьером неупорядоченного доступа (UAV). Это может повысить производительность за счет увеличения использования оборудования GPU. Однако по умолчанию без использования барьера UAV параллельное выполнение двух смежных диспетчеров может вызвать состояние гонки, если между двумя диспетчерами существует зависимость данных; или если оба диспетчера выполняют запись UAV в одни и те же регионы памяти.
Барьер UAV заставляет все ранее отправленные отправки завершить эксектирование на GPU, прежде чем последующие отправки могут начаться. Барьеры UAV используются для синхронизации между вызовами в одном списке команд, чтобы избежать гонок данных. Вы можете создать барьер для UAV с помощью метода ID3D12GraphicsCommandList::ResourceBarrier.
Барьеры UAV в DirectML
В DirectML операторы отправляются таким образом, как вычислительные шейдеры отправляются в Direct3D 12. То есть вызовы операторов могут выполняться параллельно на GPU, если между ними нет барьера UAV. Типичная модель машинного обучения содержит зависимости данных между ее операторами; например, выходные данные одного оператора вводятся в входные данные другого. Поэтому важно использовать барьеры UAV для правильной синхронизации сообщений.
DirectML гарантирует, что только считывает и никогда не записывает во входные тензоры. Он также гарантирует, что запись в выходной тензор никогда не выполняется за пределами размера тензора в байтах, указанного членом DML_BUFFER_TENSOR_DESC::TotalTensorSizeInBytes. Это означает, что зависимости данных между операторами в DirectML можно рассматривать, анализируя только входные и выходные привязки оператора.
Например, эти гарантии позволяют отправлять два оператора, которые привязывают тот же регион ресурса как входные данные, без необходимости выдавать промежуточный барьер UAV. Это всегда безопасно, так как DirectML никогда не записывает входные тензоры. В качестве другого примера всегда безопасно привязывать тензоры вывода двух одновременных вызовов операторов к одному и тому же ресурсу Direct3D 12 (если их тензоры не пересекаются), так как DirectML никогда не записывает данные за пределы границ тензора (как определено тензором DML_BUFFER_TENSOR_DESC::TotalTensorSizeInBytes).
Поскольку барьеры UAV являются формой синхронизации, ненужное использование барьеров UAV может негативно повлиять на производительность. Поэтому лучше всего использовать минимальное количество барьеров UAV, необходимых для правильной синхронизации диспетчеров в списке команд.
Пример 1
В следующем примере выходные данные оператора свертки передаются в активацию ReLU, после чего происходит нормализация по пакетам.
CONVOLUTION (conv1)
|
ACTIVATION_RELU (relu1)
|
BATCH_NORMALIZATION (batch1)
Так как зависимость данных существует между всеми тремя операторами, вам потребуется барьер UAV между каждой последовательной отправкой (см. раздел IDMLCommandRecorder::RecordDispatch).
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
Конв1)
-
d3d12CommandList->ResourceBarrier(
Барьер UAV)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
relu1)
-
d3d12CommandList->ResourceBarrier(
Барьер UAV)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
партия1)
Пример 2
MAX_POOLING (pool1)
/ \
CONVOLUTION CONVOLUTION
(conv1) (conv2)
\ /
JOIN (join1)
Здесь выходные данные пулинга передаются в два свертки, выходные данные которых затем объединяются вместе с помощью оператора JOIN. Существует зависимость данных между pool1
, с одной стороны, и conv1
и conv2
с другой; а также между conv1
и conv2
, с одной стороны, и join1
с другой. Ниже приведен один из допустимых способов выполнения этого графа.
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
пул1)
-
d3d12CommandList->ResourceBarrier(
Барьер UAV)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
Конв1)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
Конв2)
-
d3d12CommandList->ResourceBarrier(
Барьер UAV)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
Присоединиться1)
В этом случае conv1
и conv2
может выполняться параллельно на GPU, что может повысить производительность.
Требования к состоянию барьера ресурсов
Как инициатор вызова, вы несете ответственность за то, чтобы ресурсы Direct3D 12 были в правильном состоянии барьера ресурсов перед выполнением операций DirectML на графическом процессоре. DirectML не выполняет никаких барьеров перехода от вашего имени.
Перед выполнением IDMLCommandRecorder::RecordDispatch на GPU необходимо перенести все привязанные ресурсы в состояние D3D12_RESOURCE_STATE_UNORDERED_ACCESS или в состояние, неявно промотабельное в D3D12_RESOURCE_STATE_UNORDERED_ACCESS, например D3D12_RESOURCE_STATE_COMMON. После завершения этого вызова ресурсы остаются в состоянии D3D12_RESOURCE_STATE_UNORDERED_ACCESS . Дополнительные сведения см. в разделе "Привязка" в DirectML.