LINUX.ORG.RU

[PyOpenCL] Утечка памяти после каждого выполнения ядра


0

1

Пишу проект с использованием PyOpenCL и обнаружил неприятную проблему - после каждого выполнения ядра программа отъедает примерно по 1,5 МБ оперативной памяти.

Когда я писал небольшой проектик с использованием биндингов для С++, я докопался до такой причины - при каждом вызове ядра создается новое событие, которое не уничтожается по дефолту до завершения программы. Как ни странно, каждое такое событие занимает минимум 300 КБ памяти. Тогда я решил проблему динамическим созданием события, скармливанием его enqueueNDRangeKernel и уничтожением после завершения работы ядра. Само собой, на питоне такое не провернуть.

Вообще в программе используется такой алгоритм: на GPU прогоняется некоторое количество итераций, ядро завершается, данные с GPU скидываются в оперативку и записываются в файл. Далее вновь запускается ядро и т.д. Поэтому при нескольких тысячах таких циклов программа съедает все 4 ГБ оперативки.

Может кто знает, как решить эту проблему?

UPD. Проблема проявляется как при расчёте на CPU (Intel), так и на GPU (nVidia).

★★★

Ответ на: комментарий от jessey

Думаю, что не прокатит... ибо del удалит наверное только питоновскую переменную... и память, занятую через кривой API - не очистит... хотя на 100% не уверен.

BattleCoder ★★★★★ ()
Ответ на: комментарий от jessey

при условии того, что индусы написали этот деструктор и сделали это правильно. сдаётся мне, этот pyopencl банально за собой не подчищает.

enjoy your opensource!

BattleCoder ★★★★★ ()
Ответ на: комментарий от lu4nik

Значит, я прав. Пишите разработчикам =) может, у вас появится бесценный опыт копания в чужом грязном белье в исходниках этого замечательного программного продукта.

BattleCoder ★★★★★ ()
Ответ на: комментарий от BattleCoder

Тут всё немного по-другому. Дело осложняется тем, что это 1) фича 2) не pyopencl, a самого по себе OpenCL. Т.е., точно то же развлечение будет, если юзать C++ биндинги или исходный сишный API. Самое смешное в этой ситуации, что гугление не дало любых примеров кода, где ядро вызывается многократно (т.е., более нескольких раз). Тогда эта проблема не видна вообще. Т.е., считается, что ядро должно вызываться пару раз. Решение для богомерзкого С++ я нашел отчасти наугад.

Вообще надо будет почитать спецификацию на предмет непонятной нужности хранения овер 9000 событий. Ибо и Intel SDK, и nVidia SDK в этом случае ведут себя идентично.

lu4nik ★★★ ()
Ответ на: комментарий от lu4nik

Значит да, проблема в самом OpenCL. Попробуйте использовать CUDA (хотя не гарантирую, что там такой бяки не будет, сам сейчас борюсь со всякими неприятностями).

Кстати, для решения моей задачи я тоже думал кое-какое ядро запускать 100500 тыщ раз... это было один из вариантов решения =) но он так и остался в уме... решил. что лучше всё-таки одним ядром всё и считать, промежуточные результаты вычисления мне особо не нужны.

Всё-таки запуск ядра - накладная операция наверное..

BattleCoder ★★★★★ ()
Ответ на: комментарий от BattleCoder

Вообще я уже подумываю о том, чтобы кэшировать данные на GPU, чтобы обойтись парой вызовов ядра (пока что задача не сжирает весь гигабайт видеопамяти). CUDA я вряд ли буду использовать, ибо есть дедлайн, а учить CUDA и переписывать уже почти готовый код как-то не очень.

Тут сумасшедший товарищ посоветовал два реально madness варианта:
1) кончается память - перезапускать программу и начинать с места остановки!
2) выделить под своп свободные 200 ГБ на жестком диске.

lu4nik ★★★ ()
Ответ на: комментарий от lu4nik

Второй вариант и правда сумасшедший =) хотя наверное на быстродействии это не скажется особо... если всё равно на диск что-то сохраняется.

а первый вариант - почему бы и нет? попробуйте... мысль хорошая.

BattleCoder ★★★★★ ()

Проблема разрешилась неожиданным образом - оказалось, что лажа была у меня. Для отладки некоторое время назад я сохранял данные моделирования в пару списков для построения графика. Код построения я удалил, а код наполнения списков - нет. Списки ВНЕЗАПНО стали сжирать много памяти при большом числе итераций.

После удаления ненужного кода потребление памяти выровнялось и не увеличивается без дополнительных мер, что весьма радует. К тому времени я наполовину написал кэширование данных на GPU и пересылку данных большими блоками =)

lu4nik ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.