2012-11-05 5 views
19

OS X (Mountain Lion 10.8.2)에서 일부 Rcpp 코드의 프로파일 링에 관심이 있는데 실행 중에 프로파일 러가 충돌합니다.OS X에서 Rcpp 코드 프로파일 링

inline을 사용하는 장난감 예는 프로필러가 알아 차릴 수있는 충분한 시간이 걸릴 수 있도록 설계되었습니다. 나는 어느 GUI 악기를 사용하는 경우

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) 

(엑스 코드에서, 버전 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)) 악기 및 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의 주요 용도 중 하나가 R 코드의 속도를 높이는 것처럼 보이기 때문에 더 많은 정보를 찾지 않아서 놀랍지 만 잘못된 곳을 찾고 있습니다.

이것은 R 2.15.1 (x86_64-apple-darwin9.8.0), Rcpp 0.9.15 및 g ++ --version이 "i686-apple-darwin11-llvm-g ++ - 4.2를보고하는 OS X 10.8.2에 있습니다. (GCC) 4.2.1 (Apple Inc. 빌드 5658 기준) (LLVM 빌드 2336.11.00) ". 여기 아래 더크의 대답, 그리고 그의 이야기 http://dirk.eddelbuettel.com/papers/ismNov2009introHPCwithR.pdf

해결책

덕분에, 나는 구글 perftools을 사용하여 적어도 부분적인 해결책을 가지고 있습니다. 먼저 여기에서 http://code.google.com/p/gperftools/을 설치하고 C++ 코드를 컴파일 할 때 -lprofiler를 PKG_LIBS에 추가하십시오.

RcppExport SEXP start_profiler(SEXP str) { 
    ProfilerStart(as<const char*>(str)); 
    return R_NilValue; 
} 

RcppExport SEXP stop_profiler() { 
    ProfilerStop(); 
    return R_NilValue; 
} 

: 다음 중 하나를

(가) CPUPROFILE=samples.log R으로 실행 R, 모든 코드를 실행하고 종료 (또는 사용 RSCRIPT)

(b)의 온/오프 프로파일 링을 켜 두 개의 작은 유틸리티 함수를 사용하여 그런 다음 R 내에서 수행 할 수있는

.Call("start_profiler", "samples.log") 
# code that calls C++ code to be profiled 
.Call("stop_profiler") 

어느 경우 든 파일 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 

같은 출력을 생성

pprof --text /Library/Frameworks/R.framework/Resources/bin/exec/x86_64/R samples.log 

으로 바라 보았다 수 있습니다.

+1

+1 - perftools, gcc 프로파일 러 또는 valgrind가 모두 도움이 될 수 있습니다. R이 상호 작용한다는 사실은 더 많은 코드 레이어를 추가함에 따라 여기에 스패너를 던졌습니다. –

+0

내 Xcode를 업그레이드 할 때이 문제가 발생했습니다. 문제는 상어가 이전에 Rcpp 프로파일 링을 위해 완벽하게 작동했지만, 이제는 없어졌습니다. 나는 이것을 애플 버그라고 부를 수 있다고 생각한다. –

답변

4

내가 혼란 스러워요, 당신의 예는 불완전 :

  • 당신은 당신이 프로파일 러를 호출하는 방법을 보여줍니다하지 않는 (사소한) cfunction()의 호출과 cxxfunction()

  • 을 표시하지 않습니다

  • 당신이 C 또는 C++ 코드 (!)

,536,913,632 프로파일되지 않습니다 10

어쩌면 질문을 편집하여 더 명확하게 표시 할 수 있습니까?

또한이 예제를 실행하면 두 예제가 본질적으로 동일하므로 동일한 속도 결과를 제공합니다. [Rcpp는 설탕 난수 함수를 사용하여 호출 할 수 있습니다. ]

R> library(Rcpp) 
R> library(inline) 
R> 
R> 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);" 
R> 
R> 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 Rf_ScalarReal(x);" 
R> 
R> fc <- cfunction(signature(n_="int"), body=src.c) 
R> fcpp <- cxxfunction(signature(n_="int"), body=src.c, plugin="Rcpp") 
R> 
R> library(rbenchmark) 
R> 
R> print(benchmark(fc(10000L), fcpp(10000L))) 
     test replications elapsed relative user.self sys.self user.child sys.child 
1 fc(10000)   100 0.013  1  0.012  0   0   0 
2 fcpp(10000)   100 0.013  1  0.012  0   0   0 
R> 
+0

안녕하세요. 덕분에 도움을 주셔서 감사합니다. 위의 예제를 명확하게 편집했습니다. 프로파일 러는 'sample'명령으로 호출되며 C 버전의 출력을 프로파일 링중인 C임을 나타 내기 위해 포함 시켰습니다. 나는 R + C 코드로이 일반적인 접근법을 사용했지만 C++에서는 사용하지 않았다. 예제는 동일한 결과를 제공해야하며 실제로 프로필하려고하는 문제를 대표하지 않습니다. 다시 고마워, Rich – Rich

+1

나는 지금 - 나는 이것의 OS X 측면에 대해 아무것도 모른다. 똑바로 올라가는 gcc 외에도 프로파일 링에 대한 몇 가지 노트를 내 웹 사이트/이전 회담에서 'HPC Intro to R'슬라이드에 넣었습니다. r-sig-mac에서'sample'이 R toolchain에서 작동하는지 확인해야합니다. –