OS X (Mountain Lion 10.8.2) でいくつかの Rcpp コードをプロファイリングすることに興味がありますが、プロファイラーを実行するとクラッシュします。
inline
プロファイラが気付くのに十分な時間がかかるように設計された を使用したおもちゃの例。
library(Rcpp)
library(inline)
src.cpp <- "
RNGScope scope;
int n = as<int>(n_);
double x = 0.0;
for ( int i = 0; i < n; i++ )
x += (unif_rand()-.5);
return wrap(x);"
src.c <- "
int i, n = INTEGER(n_)[0];
double x = 0.0;
GetRNGstate();
for ( i = 0; i < n; i++ )
x += (unif_rand()-.5);
PutRNGstate();
return ScalarReal(x);"
f.cpp <- cxxfunction(signature(n_="integer"), src.cpp, plugin="Rcpp")
f.c <- cfunction(signature(n_="integer"), src.c)
GUI インストゥルメント (Xcode、バージョン 4.5 (4523)) またはコマンド ラインのいずれかを使用するとsample
、両方ともクラッシュします。インストゥルメントはすぐにクラッシュしますが、サンプルはクラッシュする前にサンプルの処理を完了します。
# (in R)
set.seed(1)
f.cpp(200000000L)
# (in a separate terminal window)
~ » sample R # this invokes the profiler
Sampling process 81337 for 10 seconds with 1 millisecond of run time between samples
Sampling completed, processing symbols...
[1] 81654 segmentation fault sample 81337
同じプロセスを C バージョン (つまりf.c(200000000L)
) で実行すると、Instruments と両方とも正常に動作し、次sample
のような出力が生成されます。
Call graph:
1832 Thread_6890779 DispatchQueue_1: com.apple.main-thread (serial)
1832 start (in R) + 52 [0x100000e74]
1832 main (in R) + 27 [0x100000eeb]
1832 run_Rmainloop (in libR.dylib) + 80 [0x1000e4020]
1832 R_ReplConsole (in libR.dylib) + 161 [0x1000e3b11]
1832 Rf_ReplIteration (in libR.dylib) + 514 [0x1000e3822]
1832 Rf_eval (in libR.dylib) + 1010 [0x1000aa402]
1832 Rf_applyClosure (in libR.dylib) + 849 [0x1000af5d1]
1832 Rf_eval (in libR.dylib) + 1672 [0x1000aa698]
1832 do_dotcall (in libR.dylib) + 16315 [0x10007af3b]
1382 file1412f6e212474 (in file1412f6e212474.so) + 53 [0x1007fded5] file1412f6e212474.cpp:16
+ 862 unif_rand (in libR.dylib) + 1127,1099,... [0x10000b057,0x10000b03b,...]
+ 520 fixup (in libR.dylib) + 39,67,... [0x10000aab7,0x10000aad3,...]
356 file1412f6e212474 (in file1412f6e212474.so) + 70,61,... [0x1007fdee6,0x1007fdedd,...] file1412f6e212474.cpp:16
56 unif_rand (in libR.dylib) + 1133 [0x10000b05d]
38 DYLD-STUB$$unif_rand (in file1412f6e212474.so) + 0 [0x1007fdf1c]
私が間違っていることがある場合、他の好ましい方法がある場合、またはこれが不可能な場合は、アドバイスをいただければ幸いです。Rcpp の主な用途の 1 つが R コードの高速化にあるように思われることを考えると、これに関する詳しい情報が見つからないことに驚いていますが、おそらく私は間違った場所を探しているのでしょう。
これは、OS X 10.8.2 で R 2.15.1 (x86_64-apple-darwin9.8.0)、Rcpp 0.9.15、および g++ --version レポート "i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2 .1 (Apple Inc. ビルド 5658 に基づく) (LLVM ビルド 2336.11.00)".
解決策
以下の Dirk の回答と、ここでの彼の講演http://dirk.eddelbuettel.com/papers/ismNov2009introHPCwithR.pdfのおかげで、Google perftools を使用して少なくとも部分的な解決策を得ることができました。まず、ここhttp://code.google.com/p/gperftools/からインストールし、C++ コードをコンパイルするときに PKG_LIBS に -lprofiler を追加します。その後、どちらか
(a) R を as としてCPUPROFILE=samples.log R
実行し、すべてのコードを実行して終了する (または Rscript を使用する)
(b) 2 つの小さなユーティリティ関数を使用して、プロファイルのオン/オフを切り替えます。
RcppExport SEXP start_profiler(SEXP str) {
ProfilerStart(as<const char*>(str));
return R_NilValue;
}
RcppExport SEXP stop_profiler() {
ProfilerStop();
return R_NilValue;
}
次に、R内で次のことができます
.Call("start_profiler", "samples.log")
# code that calls C++ code to be profiled
.Call("stop_profiler")
どちらの方法でも、ファイルsamples.log
にはプロファイリング情報が含まれます。これはで見ることができます
pprof --text /Library/Frameworks/R.framework/Resources/bin/exec/x86_64/R samples.log
次のような出力を生成します
Using local file /Library/Frameworks/R.framework/Resources/bin/exec/x86_64/R.
Using local file samples.log.
Removing __sigtramp from all stack traces.
Total: 112 samples
64 57.1% 57.1% 64 57.1% _unif_rand
30 26.8% 83.9% 30 26.8% _process_system_Renviron
14 12.5% 96.4% 101 90.2% _for_profile
3 2.7% 99.1% 3 2.7% Rcpp::internal::expr_eval_methods
1 0.9% 100.0% 1 0.9% _Rf_PrintValueRec
0 0.0% 100.0% 1 0.9% 0x0000000102bbc1ff
0 0.0% 100.0% 15 13.4% 0x00007fff5fbfe06f
0 0.0% 100.0% 1 0.9% _Rf_InitFunctionHashing
0 0.0% 100.0% 1 0.9% _Rf_PrintValueEnv
0 0.0% 100.0% 112 100.0% _Rf_ReplIteration
これはおそらく実際の例でより有益です。