GPU Drano является статическим инструментом анализа для программ графических процессоров. Один из анализов в GPU Drano предназначен для поиска неподвижных доступа к памяти в коде CUDA. Другой анализ, поддерживаемый графическим процессором Drano, является анализом, чтобы доказать независимость от программ графического процессора размером блока.
Современные графические процессоры переворачиваются в деформации. Все потоки в Warp выполняют операции в Lockstep. Доступ к памяти в разные местоположения памяти может быть объединен в одну нагрузку/хранилище, если память соседней или достаточно близко в памяти. Когда память, доступная к деформации, находится далеко друг от друга, для завершения транзакции памяти требуется множественная нагрузка/хранилища, и мы говорим, что доступ не предснется .
Говорят, что ядро графического процессора не зависит от размера блока , если изменить размер блока, сохраняя при этом общее количество потоков одинаковым, не нарушает функциональность программы. Это важно для правильной настройки размера блока в программах GPU, которая часто используется для повышения производительности программы.
Мы также внедрили динамический анализ для выявления неподвижных доступа, он доступен в этом репозитории.
GPU Drano реализован в качестве компилятора для LLVM с использованием реализации Google с открытым исходным кодом CUDA: gpucc . Поэтому Драно тесно связан с LLVM.
Drano требует LLVM версии 6.0 или более поздней версии. Это также требует инструментария CUDA (версия 7.5 или более поздней версии) от NVIDIA. Он был протестирован на Ubuntu 16.04 LTS, но должен работать с большинством существующих систем Linux.
Сам статический анализ не требует графического процессора. Однако для выполнения программ и для запуска динамического Anlaysis требуется графический процессор Nvidia и совместимые драйверы. Проверьте системные требования NVIDIA для получения дополнительной информации.
Подробности алгоритма и выбора дизайна можно найти в следующих документах:
Script installnrun.sh включен в проект подробно описание шагов, необходимых для создания и выполнения GPU Drano в системе Ubuntu. Запустить сценарий,
ROOT_DIR на путь к загруженной папке.sh installnrun.shЭто автоматически установит GPU Drano в систему Linux. Далее мы опишем этапы установки для установки незамеченного анализа доступа здесь. Установка для анализа независимости размера блока (также называется анализом инвариантности размера блока) может быть сделана аналогичным образом.
Получите источник LLVM:
Убедитесь, что subversion установлена. Загрузите новейшую версию LLVM:
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
Получить кланг источник:
Измените свой текущий рабочий каталог на llvm/tools/ и проверьте clang из репозитория SVN:
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
Добавить графический процессор Drano в LLVM:
Скопируйте GPU GPU Drano src/ папку в каталог llvm/lib/Transforms/UncoalescedAnalysis в вашем исходном коде:
cp -r src/abstract-execution/* llvm/lib/Transforms/UncoalescedAnalysis
cp -r src/uncoalesced-analysis/* llvm/lib/Transforms/UncoalescedAnalysis
Это создаст папку, называемую llvm/lib/Transforms/UncoalescedAnalysis/ . Мы должны зарегистрировать наш пас с помощью системы сборки LLVM cmake . Следовательно, добавьте add_subdirectory(UncoalescedAnalysis) к llvm/lib/Transforms/CMakeLists.txt
Образец файла cmakelists.txt:
$> more CMakeLists.txt
add_subdirectory(Utils)
add_subdirectory(Instrumentation)
add_subdirectory(InstCombine)
add_subdirectory(Scalar)
add_subdirectory(IPO)
add_subdirectory(Vectorize)
add_subdirectory(Hello)
add_subdirectory(ObjCARC)
add_subdirectory(Coroutines)
add_subdirectory(UncoalescedAnalysis)
Build LLVM и GPU Drano:
Из корневого каталога Drano создайте build/ каталог. Затем измените каталог на build/ каталог. Убедитесь, что Cmake установлен в системе. Выполнить следующие команды здесь:
cmake ../llvm
make
Это cmake с пути к каталогу LLVM ( ../llvm ). Cmake настраивает LLVM для вашей системы. Он должен генерировать несколько файлов в вашем текущем рабочем каталоге ( build/ ). Команда make Builds LLVM и Drano.
В идеале используйте make -j N , где n -это количество ядер для строительства, чтобы построить параллельно, так как LLVM занимает много времени на строительство.
Примечание : для компиляции LLVM требуется большое количество памяти, в частности, на шаге связывания. Если у вас есть <8 гигабайт ОЗУ, LLVM может не построить. Если это так, вы можете повторить make без опции -j . Это только перекомпиляет неудавшиеся части сборки и все же сохранит больше времени, чем не использование -j с самого начала.
Установите LLVM и GPU Drano выполнить sudo make install . Это должно установить библиотеки и двоичные файлы в местоположение по умолчанию (или указанное место). При установке локально, это руководство предполагает, что Bash может найти команду в своем пути.
Выше приведено руководство быстрого начала. Если вы не знакомы с LLVM, вы можете найти все данные для установки по адресу: http://llvm.org/docs/gettingstarted.html
Script installnrun.sh кратко описывает процесс создания драйверов NVIDIA, Toolkit и SDK. Сценарий был прокомментирован, чтобы избежать риска переоценки существующих драйверов Nvidia. Обратите внимание, что нам нужен только инструментарий и SDK, чтобы запустить статический анализ. Нам также нужны драйверы и работающий графический процессор для выполнения динамического анализа и самих программ CUDA.
Установите драйверы NVIDIA, CUDA Toolkit и SDK: пожалуйста, см. Руководство по установке NVIDIA для инструкций.
Таким образом, если вы используете недавний и популярный Linux Distro, вы сможете использовать инструмент автоматической загрузки для установки требуемых драйверов и SDK.
Если у вас уже есть необходимые драйверы и SDK, вы можете пропустить этот шаг. Вероятно, не очень хорошая идея, чтобы переопределить ваши существующие драйверы, так как это может сделать вашу систему непригодной для использования.
Вам может потребоваться G ++-Multilib для установки необходимых библиотек, требуемых clang .
Этот шаг необязательно . Простая программа CUDA, такая как «Hello World», теперь должна компилировать clang или clang++ :
clang -x cuda helloWorld.cu
В опции -x cuda явно указывается язык. Вы также можете опустить это, и Clang сделает это в качестве программы CUDA.
Примечание: вашей установке Clang, возможно, не потребуется найти несколько внутренних функций LLVM, если да, вам может потребоваться включить -lcudart . Вам также может потребоваться указание на местоположение cudart.so .
Пример:
clang -x cuda -L /usr/local/cuda/targets/x86_64-linux/lib/ -lcudart helloWorld.cu
Путь к вашему Cudart.SO может быть разным в зависимости от вашей системы.
LLVM должен был сгенерировать общий объект .so файл, называемый LLVMUncoalescedAnalysis.so build/lib/
clang генерирует отдельное устройство (код ядра графического процессора) и IR -файлы хоста (код запускается на ЦП) при составлении программ CUDA. GPU Drano анализирует IR -файлы LLVM для кода устройства.
В качестве примера, давайте проанализируем код ядра Rodinia для теста gaussian . Мы меняем каталог в rodinia_3.1/cuda/gaussian/ .
Сначала у нас есть Clang Generate LLVM IR -файлы для кода, который нас интересует:
clang++ -S -g -emit-llvm gaussian.cu
Обратите внимание, что мы компилируем с символом отладки -g , чтобы сохранить информацию отладки о местоположениях исходного кода в сгенерированном IR. Это используется для указания местоположения исходного кода с потенциальными незанятым доступом от LLVM IR.
Компиляция генерирует два файла:
gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll
gaussian.ll
Затем мы можем запустить статический анализ с помощью opt LLVM, указав путь к бинарному графическому графическому графику и указав пропуск -interproc-uncoalesced-analysis который будет запущен. Этот проход является межпроцедурным анализом для обнаружения неполаженных доступа. Он начинается с анализа самой максимальной функции в вызовом графе, а затем продолжается с анализом его Callees в топологическом порядке. Анализируя конкретную Callee, он рассматривает соединение контекста вызовов всех его абонентов. Чтобы запустить внутрипроцедурный анализ (который предполагает, что все аргументы начальной функции не зависят от идентификатора потока), укажите проход -uncoalesced-analysis , который будет запущен, а не -interproc-uncoalesced-analysis .
opt -load ../../../build/lib/LLVMUncoalescedAnalysis.so -instnamer -interproc-uncoalesced-analysis < gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll > /dev/null 2> gpuDranoResults.txt
Обратите внимание, opt считывает ИК -файл с стандартного ввода. opt записывает свой собственный неинтересный вывод, чтобы стандартно выходить, поэтому мы перенаправляем его в /dev/null GPU, вывод Drano записывается на стандартную ошибку, которая может быть перенаправлена в файл.
Чтобы сгенерировать результаты анализа словеса (IR LLVM, аннотированный с информацией о анализе), запустите opt с помощью дополнительного -debug-only=uncoalesced-analysis .
Следующая команда может быть использована для запуска анализа независимости размера блока в программе.
opt -load ../../../build/lib/LLVMBlockSizeInvarianceAnalysis.so - -instnamer -always-inline -interproc-bsize-invariance-analysis < gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll > /dev/null 2> gpuDranoResults.txt
Сгенерированные результаты для анализа незанятого доступа сообщают обо всех доступах, которые могут быть потенциально не председаны в каждом из ядра графического процессора. Например, вот результаты для анализа gaussian.cu .
Analysis Results:
Function: _Z4Fan1PfS_ii
Uncoalesced accesses: #2
-- gaussian.cu:295:59
-- gaussian.cu:295:61
Analysis Results:
Function: _Z4Fan2PfS_S_iii
Uncoalesced accesses: #4
-- gaussian.cu:312:38
-- gaussian.cu:312:35
-- gaussian.cu:312:35
-- gaussian.cu:317:23
Каждый элемент результата указывает на потенциально неподвижный доступ в исходном коде. Например, доступ к m_cuda в строке 295, столбец 59 в gaussian.cu at method Fan1() не предснется.
Аналогичным образом, сгенерированные результаты для анализа независимости размера блока идентифицируют все ядра, которые являются независимыми размером с блока!
Родиния является популярным набором программ графических процессоров, состоящих из 22 программ из разных доменов. Мы проанализировали набор и обнаружили 111 настоящих незанятых доступа, используя статический анализ. Чтобы воспроизвести результаты, вот соответствующие шаги:
Обновите конфигурацию CUDA и Drano в rodinia_3.1/common/make.config . Установите CUDA_DIR и SDK_DIR с NVIDIA Toolkit и PATHS SDK. Обновить opt с путем к графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому графическому LLVMUncoalescedAnalysis.so пути.
Перейдите в каталог тестов rodinia_3.1/cuda .
Компиляция тестов:
sh compile.sh
sh run-analysis.sh
Анализ каждого эталона генерирует результаты в соответствующей папке в журналах с именем log_<filename> .
./summarize-results.sh
Nvidia предоставляет набор образцов CUDA, которые можно использовать для различных применений. Мы проанализировали набор для определения независимых ядра размером с блока в образцах. Чтобы воспроизвести результаты, шаги:
Обновите HOME переменную в NVIDIA_CUDA-8.0_Samples/common/drano.mk в каталог корневого графического процессора.
Установите OpenGL (необходимо для составления нескольких тестов). На Ubuntu можно использовать следующую команду:
sudo apt-get install freeglut3-dev
Перейдите в каталог NVIDIA_CUDA-8.0_Samples
Компиляция тестов:
sh compile.sh
sh run-analysis.sh
Анализ каждого эталона генерирует результаты в соответствующей папке в журналах с именем log_<filename> .
./summarize-bsize-independence.sh