فرق الأداء بين ركبارماديلو و أرماديلو

StackOverflow https://stackoverflow.com//questions/23050073

  •  21-12-2019
  •  | 
  •  

سؤال

أحاول أن أفهم الفرق في الأداء بين وظيفة مكتوبة في ركبارماديلو واحد مكتوب في برنامج مستقل ج using باستخدام مكتبة أرماديلو.على سبيل المثال ، ضع في اعتبارك الوظيفة البسيطة التالية التي تحسب معاملات نموذج خطي باستخدام صيغة الكتاب المدرسي التقليدية.

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
void simpleLm(NumericMatrix Xr, NumericMatrix yr) {
   int n = Xr.nrow(), k = Xr.ncol();
   mat X(Xr.begin(), n, k, false);
   colvec y(yr.begin(), yr.nrow(), false);

   colvec coef = inv(X.t()*X)*X.t()*y;
}

هذا يستغرق حوالي 6 ثوان لتشغيل مع 1000000x100 مصفوفة ل X.أشارت بعض التوقيتات في الكود (غير معروض) إلى أن كل الوقت يتم إنفاقه على coef حساب.

X <- matrix(rnorm(1000000*100), ncol=100)
y <- matrix(rep(1, 1000000))
system.time(simpleLm(X,y))

 user  system elapsed 
  6.028   0.009   6.040

الآن النظر في وظيفة مشابهة جدا مكتوبة في ج that ثم يتم تجميعها مع g++.

#include <iostream>
#include <armadillo>
#include <chrono>
#include <cstdlib>

using namespace std;
using namespace arma;

int main(int argc, char **argv) {
    int n = 1000000;
    mat X = randu<mat>(n,100);
    vec y = ones<vec>(n);

    chrono::steady_clock::time_point start = chrono::steady_clock::now();

    colvec coef = inv(X.t()*X)*X.t()*y;

    chrono::steady_clock::time_point end = chrono::steady_clock::now();

    chrono::duration<double, milli> diff = end - start;

    cout << diff.count() << endl;

    return 0;
}

هنا حساب coef متغير يستغرق سوى حوالي 0.5 ثانية ، أو فقط 1/12 الوقت كما هو الحال عندما فعلت مع ركبارماديلو.

أنا باستخدام ماك أوس س 10.9.2 مع ص 3.1.0 ، ركب 0.11.1 و ركبارماديلو 0.4.200.0.أنا جمعت المثال ركب باستخدام وظيفة سورسيكب.يستخدم المثال ج standalone مستقل أرماديلو 4.200.0 ، وأنا أيضا تثبيت مترجم فورتران لماك باستخدام البيرة (brew install gfortran).

هل كانت مفيدة؟

المحلول

تخمين سريع:يستخدم البرنامج الأصلي بلاس المعجل, كنت ص بناء لا.

يتم استزراع "مصفوفة الرياضيات" الفعلية من قبل أرماديلو إلى مكتبة بلاس.مع ركبارماديلو ، يمكنك الحصول على ما بنيت ص ضد.مع برنامج أصلي ، ربما تستخدم شيئا آخر.يمكن أن تكون بسيطة مثل البرنامج الخاص بك الحصول على استخدام المكتبات تسريع في حين ر لا-أنا لا أعرف حقا وأنا لا تستخدم نظام التشغيل العاشر.

ولكن لإثبات ، على بلدي (أنا 7 ، لينكس) آلة ، مرات قريبة متطابقة.

أولا ، برنامجك ، دون تغيير:

edd@max:/tmp$ g++ -std=c++11 -O3 -o abiel abiel.cpp -larmadillo -llapack
edd@max:/tmp$ ./abiel 
2454
edd@max:/tmp$ 

ثانيا ، البرنامج ملفوفة في شيء ص يمكن استدعاء (انظر أدناه):

R> library(Rcpp)
R> sourceCpp("/tmp/abielviaR.cpp")
R> abielDemo()
2354.41
[1] TRUE
R> 

عن نفسه.

قانون abielviaR.cpp يتبع.

#include <RcppArmadillo.h>
#include <chrono>

using namespace std;
using namespace arma;

// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
bool abielDemo() {
    int n = 1000000;
    mat X = randu<mat>(n,100);
    vec y = ones<vec>(n);

    chrono::steady_clock::time_point start = chrono::steady_clock::now();
    colvec coef = inv(X.t()*X)*X.t()*y;
    chrono::steady_clock::time_point end = chrono::steady_clock::now();
    chrono::duration<double, milli> diff = end - start;
    Rcpp::Rcout << diff.count() << endl;

    return true;
}

بس كنت حقا لا ينبغي حساب شريان الحياة عبر (ش ' س)^(-1) س على الرغم من.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top