Intruments Call Tree 破坏了 R、C++ 和 Fortran 的混合

Intruments Call Tree broken mix of R, C++ and Fortran

我正在尝试分析 OpenMx 的一个函数,一个包含 C++ 和 Fortran 代码的 R 包,CPU 时间。我的操作系统是 OS X 10.10。我已阅读 section regarding this topic in the R manual. This section and this post 引导我尝试 Instruments。这是我所做的

  1. 打开的工具
  2. 选择时间分析器模板
  3. 按下记录
  4. 使用 RStudio 启动我的 R 脚本

我得到以下输出:. The command line tool sample returns 相同的输出。

问题是 omxunsafedgemm_ 似乎会直接从主线程调用。但是,这是一个低级 Fortran 函数。它总是由名为 omxDGEMM 的 C++ 函数调用。在这个例子中 omxDGEMM 首先被 omxCallRamExpection 调用(所以几乎在调用树的底部)。 omxDGEMM的总时间为0。因此,分析信息目前没有用。

在原始版本的包中omxDGEMM被定义为inline。我改变了这个,希望它能解决这个问题。此情况并非如此。 omxunsafedgemm 像那样被 omxDGEMM 调用

F77_CALL(omxunsafedgemm)(&transa, &transb,
                        &(nrow), &(ncol), &(nmid),
                        &alpha, a->data, &(a->leading), 
                        b->data, &(b->leading),&beta, result->data, &(result->leading));

关于如何获得合理的分析器输出有什么想法吗?

如果 OpenMx 二进制文件是通过 getOpenMx.R 从 OpenMx 网站获得的,那么它将使用 gcc/gfortran 进行编译。如果它来自 CRAN,它将使用 OS X 编译器 LLVM 等进行编译(但它缺少并行计算,因为 OpenMP 与 LLVM 不兼容)。因此,您可以尝试使用其他二进制文件来查看用于分析的标签是否更好。请告诉我们您使用的是哪个版本以及更改版本是否有帮助。

此问题是由 gfortran 编译器的 -O2 标志引起的,R 默认使用该标志。 -O2 标志打开所有 -O1 标志启用的优化步骤以及更多(参见 gcc manual page 98). One of the optimization flags that the -O1 flags enables is -fomit-frame-pointer. Instruments needs the frame pointers to know the parent of a call frame (see this talk)。

因此,改变

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 秒)。