#c #memory-management #profiling #cuda
#c #управление памятью #профилирование #cuda
Вопрос:
Вскоре мне будет поручено создать надлежащий профиль памяти для кода, написанного на C / C и использующего CUDA для использования преимуществ обработки на GPU.
Моими первоначальными мыслями было бы создать макросы и перегрузки операторов, которые позволили бы мне отслеживать вызовы malloc, free, delete и new в моем исходном коде. Я бы просто мог включить другой заголовок и использовать __FILE__ and __LINE__
макросы для печати вызовов памяти в файл журнала. Этот тип стратегии находится здесь: http://www.almostinfinite.com/memtrack.html
Каков наилучший способ отслеживать это использование в связанной сторонней библиотеке? Я предполагаю, что я в значительной степени смогу отслеживать использование памяти только до и после вызовов функций, правильно? В моем сценарии макроса / перегрузки я могу просто отслеживать размер запросов, чтобы выяснить, сколько памяти запрашивается. Как я смогу определить, сколько использует сторонняя библиотека? Я также понимаю, что отслеживание «свободно» на самом деле не дает вам никакого представления о том, сколько кода используется в любой конкретный момент времени, потому что он не обязательно возвращается в ОС. Я ценю любое обсуждение этого вопроса.
Я действительно не хочу использовать какие-либо инструменты профилирования памяти, такие как Totalview или valgrind, потому что они обычно выполняют много других вещей (проверка границ и т.д.), Которые, похоже, замедляют работу программного обеспечения. Еще одна причина этого в том, что я хочу, чтобы это было несколько потокобезопасно — программное обеспечение использует MPI, я полагаю, для запуска процессов. Я собираюсь попытаться профилировать это в режиме реального времени, чтобы я мог выводить данные в файлы журналов или что-то, что может быть прочитано другим процессом, чтобы визуализировать использование памяти во время работы программного обеспечения. Это также в первую очередь будет выполняться в среде Linux.
Спасибо
Ответ №1:
Возможно, опция компоновщика —wrap = symbol может вам помочь. Действительно хороший пример можно найти здесь: man ld
Ответ №2:
Может быть, valgrind и инструмент Massif?
Комментарии:
1. В частности, упоминалось, что я не собираюсь использовать сверхмощный инструмент профилирования. Я хочу иметь возможность запускать это, поскольку я запускаю свое программное обеспечение с небольшим влиянием на производительность.
Ответ №3:
Чтобы отслеживать потребление памяти в реальном времени моими программами в Linux, я просто читаю /proc/[pid]/stat
. Это довольно легкая операция, в вашем случае она может быть незначительной, если сторонняя библиотека, которую вы хотите отслеживать, выполняет последующую работу. Если вы хотите получить информацию о памяти во время работы библиотеки сторонних разработчиков, вы можете прочитать stat
файл в независимый поток или в другой процесс. (Пик памяти редко добавляется до или после вызовов функций ! …)
Что касается CUDA / GPU, я думаю, gDEBugger мог бы вам помочь. Я не уверен, но анализатор памяти не сильно влияет на производительность.
Ответ №4:
Вы могли бы попробовать профилировщик кучи PerfTools от Google:
http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html
Это очень легкий; он буквально заменяет malloc / calloc / realloc / свободно добавлять инструментальный код. В основном он тестируется на платформах Linux.
Если вы скомпилировали с использованием символов отладки, а ваши сторонние библиотеки поставляются с вариантами debug-version, PerfTools должен работать очень хорошо. Если у вас нет библиотек отладочных символов, создайте свой код с использованием отладочных символов в любом случае. Это дало бы вам подробные номера для вашего кода, а все оставшееся может быть атрибутами сторонней библиотеки.
Ответ №5:
Если вы не хотите использовать «внешний» инструмент, вы можете попробовать использовать такие инструменты, как:
-
Он устанавливает обработчики для malloc, realloc и free и записывает каждую операцию в файл. Смотрите примеры использования кода в Википедии, которую я выложил.
-
Это библиотека, которую вы можете использовать в своем коде и которая может обнаруживать утечки памяти, отдельные ошибки и использование недопустимых адресов. Вы также можете отключить его во время компиляции с помощью -DDMALLOC_DISABLE .
В любом случае, я бы предпочел не использовать такой подход. Вместо этого я предлагаю вам попробовать провести стресс-тест вашего приложения во время его запуска на тестовом сервере с помощью valgrind (или любого эквивалентного инструмента) и убедиться, что вы правильно распределяете память, а затем позволить приложению запускаться без какой-либо проверки выделения памяти в рабочей среде, чтобы максимизировать скорость. Но, на самом деле, это зависит от того, что делает ваше приложение и каковы ваши потребности.
Ответ №6:
Вы могли бы использовать профилировщик, входящий в состав Visual Studio 2010 Premium и Ultimate.
Это позволяет вам выбирать между различными методами измерения производительности, наиболее полезным для вас, вероятно, будет выборка процессора, потому что она замораживает вашу программу через произвольные промежутки времени и определяет, какие функции она выполняет в данный момент, тем самым не заставляя вашу программу работать существенно медленнее.
Комментарии:
1. Отредактированный вопрос, отражающий, что я, вероятно, не собираюсь запускать это в Windows так часто, как Linux
Ответ №7:
Я считаю, что на этот вопрос есть два очень разных ответа. Один для C / C . И вторая для CUDA land.
На процессоре:
Я написал свои собственные замены для new и delete. Они были ужасно медленными и не очень помогли. Я использовал totalview. Мне нравится totalview для отладки в OpenMP, но я согласен, что он очень медленный для отладки в памяти. Я никогда не пробовал valgrind. Я слышал похожие вещи.
Единственный инструмент отладки памяти, с которым я столкнулся, который стоит того, — это проверка памяти Intel Parallel Inspector. Примечание: Поскольку я студент, я смог получить образовательную лицензию по дешевке.Тем не менее, это потрясающе. Мне потребовалось двенадцать минут, чтобы найти утечку памяти, скрытую в полумиллионе строк кода — я не выпускал объект с ошибкой, который я поймал и проигнорировал. Мне так нравится эта часть программного обеспечения, что, когда мой raid вышел из строя / Win 7 съела мой компьютер (думаю, автоматическое обновление и перестройка raid одновременно), я остановил все и перестроил компьютер, потому что знал, что на перестройку двойной загрузки (48 часов) у меня уйдет меньше времени, чем на поиск утечки памяти другим способом. Если вы не верите моим диковинным заявлениям, загрузите ознакомительную версию.
На графическом процессоре:
Я думаю, вам не повезло. Для решения всех проблем с памятью в CUDA мне, по сути, пришлось создавать собственные инструменты и оболочки cudaMalloc
и т.д. Самостоятельно. Это некрасиво. nSight действительно дает вам что-то, но на данный момент, не намного больше, чем просто «вот сколько вы выделили прямо сейчас. И на этой печальной ноте, почти каждая проблема с производительностью, с которой я сталкивался с CUDA, напрямую зависела от моих шаблонов доступа к памяти (это или размер моего блока потока).
Комментарии:
1. Что касается сторонних разработчиков, я нахожу это щекотливым. У меня не было большого опыта — некоторое время назад я возился с библиотекой FPGA — но опять же, я в основном застрял на написании собственной оболочки, которая была довольно неэффективной (как во время кодирования, так и в отладке / профилировании).