Perfilando código Rcpp en OS X
Estoy interesado en perfilar algunos códigos Rcpp en OS X (Mountain Lion 10.8.2), pero el generador de perfiles se bloquea cuando se ejecuta.
Ejemplo de juguete, usandoinline
, solo diseñado para tomarse el tiempo suficiente para que un perfilador lo note.
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)
Si utilizo los Instrumentos GUI (en Xcode, versión 4.5 (4523)) o la línea de comandossample
, ambos fallan: los instrumentos fallan de inmediato, mientras que la muestra completa el procesamiento de las muestras antes de fallar:
# (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
Si hago el mismo proceso pero con la versión C (es decir,f.c(200000000L)
) ambos instrumentos ysample
trabajar bien y producir resultados como
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]
Realmente apreciaría algún consejo sobre si hay algo que esté haciendo mal, si hay alguna otra forma preferida, o si esto no es posible. Dado que uno de los usos principales de Rcpp parece ser acelerar el código R, me sorprende no encontrar más información sobre esto, pero quizás estoy buscando en el lugar equivocado.
Esto está en OS X 10.8.2 con R 2.15.1 (x86_64-apple-darwin9.8.0), Rcpp 0.9.15, y g ++ --version informa "i686-apple-darwin11-llvm-g ++ - 4.2 (GCC) 4.2 .1 (basado en Apple Inc. compilación 5658) (LLVM compilación 2336.11.00) ".
Una soluciónGracias a la respuesta de Dirk a continuación, y su charla aquíhttp://dirk.eddelbuettel.com/papers/ismNov2009introHPCwithR.pdf, Tengo al menos una solución parcial usando Google perftools. Primero, instale desde aquíhttp://code.google.com/p/gperftools/y agregue -lprofiler a PKG_LIBS al compilar el código C ++. Entonces tambien
(a) Ejecutar R comoCPUPROFILE=samples.log R
, ejecute todo el código y salga (o use Rscript)
(b) Use dos pequeñas funciones de utilidad para activar / desactivar la creación de perfiles:
RcppExport SEXP start_profiler(SEXP str) {
ProfilerStart(as<const char*>(str));
return R_NilValue;
}
RcppExport SEXP stop_profiler() {
ProfilerStop();
return R_NilValue;
}
Entonces, dentro de R puedes hacer
.Call("start_profiler", "samples.log")
# code that calls C++ code to be profiled
.Call("stop_profiler")
de cualquier manera, el archivosamples.log
contendrá información de perfil. Esto se puede ver con
pprof --text /Library/Frameworks/R.framework/Resources/bin/exec/x86_64/R samples.log
que produce salida como
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
lo que probablemente sería más informativo en un ejemplo real.