Я выполняю monte carlo sweeps на популяции реплик моей системы с использованием ядер OpenCL. После начальной фазы отладки я увеличил некоторые аргументы до более реалистичных значений и заметил, что программа внезапно сжигает большие объемы памяти хоста. Я выполняю 1000 разверток на около 4000 реплик, каждая развертка состоит из 2 ячеек. Это приводит к примерно 8 миллионам вызовов ядра.Ядро ядра OpenCL с большим количеством памяти хоста
Источником использования памяти было легко найти (см. Снимок экрана).
- В то время как выполнение ядра выполняется в очереди, использование памяти увеличивается.
- В то время как ядра используют использование памяти, он остается постоянным.
- Как только ядра заканчиваются, использование переходит в исходное состояние.
- Я не выделял никакой памяти, как можно видеть в моментальных снимках памяти.
Это означает, что драйвер OpenCL использует память. Я понимаю, что он должен хранить копию всех аргументов при вызове ядра, а также глобальный и локальный размер рабочей группы, но это не складывается.
Максимальное использование памяти пиковой памяти - 4,5 ГБ. Перед заражением использовались ядра размером около 250 МБ. Это означает, что OpenCL использовал около 4,25 ГБ для 8 миллионов вызовов, т. Е. Около полукилограмм на вызов.
Так что мои вопросы:
- Это вид использования памяти нормально и следовало ожидать?
- Есть ли хорошие/известные методы сокращения использования памяти?
- Возможно, я не должен ставить в очередь столько ядер одновременно, но как бы это сделать, не вызывая синхронизации, например. с
clFinish()
?
Попробуйте 'clFlush' каждые 100 или 1000 вызовов ядра или даже реже, если вы заметите, что это повредит производительности. Это неблокирующая команда, которая выведет все ранее запрошенные команды на устройство. – doqtor
Спасибо за подсказку! Я добавил «clFlush» после каждых 1000 вызовов ядра и немного улучшил его. Использование пиковой памяти снизилось до 3,5 ГБ, а пик намного короче, т. Е. Нисходящий наклон начинается гораздо раньше, но не столь крут. Влияние на производительность либо мало, либо не существует, я не вижу ничего. – Gigo
ОК, попробуйте 'clWaitForEvents'.Ячейки Enqueue 1000 добавят событие на последнем, затем вставьте еще 999 ядер и вызовите 'clWaitForEvents'. Это заставит его дождаться завершения 1000-го ядра, пока в очереди еще будут 999 ядер. Затем повторите все так же. – doqtor