Копирование и доступ к данным ресурсов
Флаги использования указывают, как приложение намерено использовать данные ресурсов, чтобы разместить ресурсы в наиболее эффективной области памяти. Данные ресурсов копируются между ресурсами, чтобы ЦП или GPU могли получить доступ к нему, не влияя на производительность.
Не обязательно думать о ресурсах как созданных в памяти видео или системной памяти, либо решить, следует ли среде выполнения управлять памятью. В архитектуре модели драйвера WDDM (Windows Display Driver Model) приложения создают ресурсы Direct3D с различными флагами использования, чтобы указать, как приложение намерено использовать данные ресурсов. Эта модель драйвера виртуализирует память, используемую ресурсами; Это ответственность за операционную систему, драйвер или память диспетчера памяти, чтобы разместить ресурсы в наиболее эффективной области памяти, учитывая ожидаемое использование.
По умолчанию ресурсы будут доступны gpu. Существуют случаи, когда данные ресурсов должны быть доступны ЦП. Копирование данных ресурсов вокруг, чтобы соответствующий процессор смог получить доступ к нему, не влияя на производительность, требует некоторых знаний о том, как работают методы API.
Копирование данных ресурсов
Ресурсы создаются в памяти при выполнении вызова Create Direct3D. Их можно создавать в видеопамяти, системной памяти или любом другом виде памяти. Так как модель драйвера WDDM виртуализирует эту память, приложения больше не должны отслеживать тип ресурсов памяти.
В идеале все ресурсы будут находиться в видеопамяти, чтобы графический процессор может иметь немедленный доступ к ним. Однако иногда требуется для ЦП считывать данные ресурсов или gpu, чтобы получить доступ к данным ресурсов ЦП, в который записывался ЦП. Direct3D обрабатывает эти различные сценарии путем запроса приложения указать использование, а затем предлагает несколько методов для копирования данных ресурсов при необходимости.
В зависимости от того, как был создан ресурс, не всегда можно напрямую получить доступ к базовым данным. Это может означать, что данные ресурса должны быть скопированы из исходного ресурса в другой ресурс, доступный соответствующим обработчиком. С точки зрения Direct3D ресурсы по умолчанию можно получить непосредственно с помощью GPU, динамические и промежуточные ресурсы можно напрямую получить через ЦП.
После создания ресурса его использование не может быть изменено. Вместо этого скопируйте содержимое одного ресурса в другой ресурс, созданный с другим использованием. Вы копируете данные ресурсов из одного ресурса в другой или копируете данные из памяти в ресурс.
Существует два основных типа ресурсов: сопоставимые и не сопоставленные. Ресурсы, созданные с динамическим или промежуточным использованием, сопоставляются, а ресурсы, созданные с использованием по умолчанию или неизменяемыми, не сопоставляются.
Копирование данных среди ресурсов, не относящихся к сопоставлению, очень быстро, так как это наиболее распространенный случай и оптимизирован для эффективной работы. Так как эти ресурсы не доступны напрямую ЦП, они оптимизированы так, чтобы GPU могли быстро управлять ими.
Копирование данных между сопоставимыми ресурсами является более проблематичным, так как производительность будет зависеть от использования ресурса, с которым был создан ресурс. Например, GPU может считывать динамический ресурс довольно быстро, но не может записывать их, и GPU не может читать или записывать в промежуточные ресурсы напрямую.
Приложения, которые хотят скопировать данные из ресурса с использованием по умолчанию в ресурс с промежуточным использованием (чтобы ЦП считывал данные , т. е. проблема обратного чтения GPU) должна сделать это с осторожностью. См. сведения о доступе к данным ресурсов ниже.
Доступ к данным ресурса
Для доступа к ресурсу требуется сопоставление ресурса; Сопоставление по сути означает, что приложение пытается предоставить ЦП доступ к памяти. Процесс сопоставления ресурса, чтобы ЦП смог получить доступ к базовой памяти, может привести к некоторым узким местам производительности, и по этой причине необходимо заботиться о том, как и когда выполнять эту задачу.
Производительность может прервать работу, если приложение пытается сопоставить ресурс в неправильное время. Если приложение пытается получить доступ к результатам операции до завершения этой операции, произойдет застой конвейера.
Выполнение операции карты в неправильное время может привести к серьезному снижению производительности, заставив GPU и ЦП синхронизироваться друг с другом. Эта синхронизация возникает, если приложение хочет получить доступ к ресурсу до завершения копирования GPU в ресурс, который ЦП может сопоставить.
Рекомендации по производительности
Лучше всего рассматривать компьютер как компьютер, работающий как параллельная архитектура с двумя основными типами процессоров: один или несколько ЦП и один или несколько GPU. Как и в любой параллельной архитектуре, оптимальная производительность достигается, когда каждый процессор планируется с достаточной работой, чтобы предотвратить его простой, и когда работа одного процессора не ожидает работы другого.
Худший сценарий параллелизма GPU и ЦП — это необходимость принудительного ожидания одного процессора, чтобы ждать результатов работы, выполняемой другим. Direct3D удаляет эту стоимость, делая методы копирования асинхронными; Копия не обязательно выполняется по времени возврата метода.
Преимуществом этого является то, что приложение не платит затраты на производительность фактического копирования данных до тех пор, пока ЦП не обращается к данным, то есть при вызове карты. Если метод Map вызывается после фактического копирования данных, производительность не возникает. С другой стороны, если метод Map вызывается перед копированием данных, произойдет свал конвейера.
Асинхронные вызовы в Direct3D (которые являются подавляющей частью методов и особенно вызовов отрисовки) хранятся в том, что называется буфером команд. Этот буфер является внутренним для графического драйвера и используется для пакетных вызовов базового оборудования, чтобы дорогостоящий переход с пользовательского режима в режим ядра в Microsoft Windows происходит как можно реже.
Буфер команд очищается, что приводит к переключении режима пользователя или ядра в одной из четырех ситуаций, которые приведены ниже.
- Вызывается представление.
- Flush вызывается.
- Буфер команд заполнен; его размер является динамическим и управляется операционной системой и графическим драйвером.
- ЦП требует доступа к результатам команды, ожидая выполнения в буфере команд.
Из четырех описанных выше ситуаций число четыре является наиболее важным для производительности. Если приложение выдает вызов для копирования ресурса или подресурса, этот вызов помещается в буфер команд.
Если приложение попытается сопоставить промежуточный ресурс, который был целевым объектом вызова копирования перед очисткой буфера команд, произойдет свал конвейера, так как не только вызов метода Copy должен выполняться, но и все остальные буферные команды в буфере команд также должны выполняться. Это приведет к синхронизации GPU и ЦП, так как ЦП будет ожидать доступа к промежуточному ресурсу, пока GPU пустит буфер команд и, наконец, заполняет ресурс ЦП. После завершения копирования GPU ЦП начнет получать доступ к промежуточному ресурсу, но в это время GPU будет сидеть бездействия.
Это часто происходит во время выполнения, что значительно снижает производительность. Поэтому сопоставление ресурсов, созданных с использованием по умолчанию, должно выполняться с осторожностью. Приложение должно ждать достаточно долго, чтобы буфер команд был очищен, и поэтому все эти команды завершают выполнение, прежде чем пытаться сопоставить соответствующий промежуточный ресурс.
Сколько времени должно ожидать приложение? По крайней мере два кадра, так как это позволит максимально использовать параллелизм между ЦП и GPU. Способ работы GPU заключается в том, что в то время как приложение обрабатывает кадр N, отправляя вызовы в буфер команд, GPU занят выполнение вызовов из предыдущего кадра N-1.
Таким образом, если приложение хочет сопоставить ресурс, который создается в памяти видео и копирует ресурс в кадре N, этот вызов фактически начнет выполняться в кадре N+1, когда приложение отправляет вызовы для следующего кадра. Копия должна быть завершена, когда приложение обрабатывает кадр N+2.
Кадр | Состояние GPU/ЦП |
---|---|
N |
|
N+1 |
|
N+2 |
|
N+3 |
|
N+4 | ... |
Связанные темы