Intruments Call Tree - битая смесь R, C++ и Fortran
Я пытаюсь профилировать функцию OpenMx, R-пакета, содержащего код C++ и Fortran, для процессорного времени. Моя операционная система - OS X 10.10. Я прочитал раздел по этой теме в руководстве по R. Этот раздел и этот пост заставляют меня попробовать инструменты. Вот что я сделал
- Открытые инструменты
- Выберите шаблон Time Profiler
- Прессованная запись
- Запустил мой R скрипт с использованием RStudio
Я получаю следующий вывод: , Образец инструмента командной строки возвращает тот же результат.
Проблема в том, что это выглядит omxunsafedgemm_
будет вызван непосредственно из основного потока. Однако это низкоуровневая функция Фортрана. Он всегда вызывается функцией C++, называемой omxDGEMM
, В этом примере omxDGEMM
сначала вызывается omxCallRamExpection
(так почти в нижней части дерева вызовов). Общее время omxDGEMM
равно 0. Таким образом, информация профилирования в настоящее время бесполезна.
В оригинальной версии пакета omxDGEMM
определяется как встроенный. Я изменил это в надежде, что это решит проблему. Это был не тот случай. omxunsafedgemm
называется omxDGEMM
как это
F77_CALL(omxunsafedgemm)(&transa, &transb,
&(nrow), &(ncol), &(nmid),
&alpha, a->data, &(a->leading),
b->data, &(b->leading),&beta, result->data, &(result->leading));
Есть идеи, как получить разумный вывод профилировщика?
2 ответа
Эта проблема вызвана -O2
флаг компилятора gfortran, который R использует по умолчанию. -O2
флаг включает все этапы оптимизации, которые -O1
flag enable и многое другое (см. руководство по gcc, стр. 98). Один из флагов оптимизации, который -O1
Флаги позволяют это -fomit-frame-pointer
, Инструментам нужны указатели фрейма, чтобы знать родителя фрейма вызова (см. Этот разговор).
Таким образом, изменяя
FFLAGS = -g -O2 $(LTO)
в
FFLAGS = -g -O2 -fno-omit-frame-pointer $(LTO)
в ${R_HOME}/etc/Makeconf
решает проблему. Для меня R_HOME=/Library//Frameworks/R.framework/Versions/3.2/Resources
Просто опуская -O2
также решает проблему, но делает OpenMx значительно медленнее (в моем случае 200 против 30 секунд).
Если бинарный файл OpenMx поступил с веб-сайта OpenMx через getOpenMx.R, то он был бы скомпилирован с помощью gcc/gfortran. Если бы он пришел из CRAN, он был бы скомпилирован с компиляторами OS X LLVM и т. Д. (Но ему не хватало бы параллельных вычислений, потому что OpenMP не совместим с LLVM). Таким образом, вы можете попробовать другой двоичный файл, чтобы увидеть, лучше ли теги для профилирования. Пожалуйста, дайте нам знать, какую версию вы использовали и помогла ли смена версии.