Mex函数比相同的C++;代码 在C++中运行程序时,它运行速度比使用Matlab函数调用的Matlab程序慢。p>
我尝试了一些示例代码来测试这一点,这证实了我的怀疑: 使用C++:Mex函数比相同的C++;代码 在C++中运行程序时,它运行速度比使用Matlab函数调用的Matlab程序慢。p>,c++,matlab,runtime,mex,C++,Matlab,Runtime,Mex,我尝试了一些示例代码来测试这一点,这证实了我的怀疑: 使用C++: 函数为-0.012s,C++代码为0.108s。这种趋势也适用于更大的阵列尺寸为什么?这是一种让McEX函数运行C++代码的方法吗?< > /p> < p>作为上述评论中的“PrAtErReIn”状态,您可能没有对C++代码进行优化。 以下是未经优化的代码LLVMIR(伪程序集)的内容: ; ModuleID = 'test.cpp' target datalayout = "e-m:e-i64:64-f80:128-n8:1
函数为-0.012s,C++代码为0.108s。这种趋势也适用于更大的阵列尺寸<“强”>为什么?这是一种让McEX函数运行C++代码的方法吗?< <强> > /p> < p>作为上述评论中的“PrAtErReIn”状态,您可能没有对C++代码进行优化。 以下是未经优化的代码LLVMIR(伪程序集)的内容:
; ModuleID = 'test.cpp'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@_ZZ7processPiS_E3dim = internal constant [2 x i32] [i32 1, i32 10000], align 4
@.str = private unnamed_addr constant [4 x i8] c"%f\0A\00", align 1
; Function Attrs: uwtable
define void @_Z7processPiS_(i32* %a, i32* %b) #0 {
%1 = alloca i32*, align 8
%2 = alloca i32*, align 8
%barData = alloca [20000 x i32], align 16
%begin = alloca i64, align 8
%i = alloca i32, align 4
%j = alloca i32, align 4
%end = alloca i64, align 8
%elapsed_secs = alloca double, align 8
store i32* %a, i32** %1, align 8
store i32* %b, i32** %2, align 8
%3 = call i64 @clock() #3
store i64 %3, i64* %begin, align 8
store i32 0, i32* %i, align 4
br label %4
; <label>:4 ; preds = %34, %0
%5 = load i32* %i, align 4
%6 = load i32* getelementptr inbounds ([2 x i32]* @_ZZ7processPiS_E3dim, i32 0, i64 1), align 4
%7 = icmp slt i32 %5, %6
br i1 %7, label %8, label %37
; <label>:8 ; preds = %4
store i32 0, i32* %j, align 4
br label %9
; <label>:9 ; preds = %30, %8
%10 = load i32* %j, align 4
%11 = load i32* %i, align 4
%12 = icmp slt i32 %10, %11
br i1 %12, label %13, label %33
; <label>:13 ; preds = %9
%14 = load i32* %i, align 4
%15 = sext i32 %14 to i64
%16 = load i32** %1, align 8
%17 = getelementptr inbounds i32* %16, i64 %15
%18 = load i32* %17, align 4
%19 = load i32* %j, align 4
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds [20000 x i32]* %barData, i32 0, i64 %20
store i32 %18, i32* %21, align 4
%22 = load i32* %i, align 4
%23 = sext i32 %22 to i64
%24 = load i32** %2, align 8
%25 = getelementptr inbounds i32* %24, i64 %23
%26 = load i32* %25, align 4
%27 = load i32* %j, align 4
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds [20000 x i32]* %barData, i32 0, i64 %28
store i32 %26, i32* %29, align 4
br label %30
; <label>:30 ; preds = %13
%31 = load i32* %j, align 4
%32 = add nsw i32 %31, 1
store i32 %32, i32* %j, align 4
br label %9
; <label>:33 ; preds = %9
br label %34
; <label>:34 ; preds = %33
%35 = load i32* %i, align 4
%36 = add nsw i32 %35, 1
store i32 %36, i32* %i, align 4
br label %4
; <label>:37 ; preds = %4
%38 = call i64 @clock() #3
store i64 %38, i64* %end, align 8
%39 = load i64* %end, align 8
%40 = load i64* %begin, align 8
%41 = sub nsw i64 %39, %40
%42 = sitofp i64 %41 to double
%43 = fdiv double %42, 1.000000e+06
store double %43, double* %elapsed_secs, align 8
%44 = load double* %elapsed_secs, align 8
%45 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double %44)
ret void
}
; Function Attrs: nounwind
declare i64 @clock() #1
declare i32 @printf(i8*, ...) #2
; Function Attrs: uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%a = alloca [10000 x i32], align 16
%b = alloca [10000 x i32], align 16
store i32 0, i32* %1
%2 = getelementptr inbounds [10000 x i32]* %a, i32 0, i32 0
%3 = getelementptr inbounds [10000 x i32]* %b, i32 0, i32 0
call void @_Z7processPiS_(i32* %2, i32* %3)
ret i32 0
}
attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame- pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp- math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame- pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp- math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer- elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no- nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp- math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.6.2 (tags/RELEASE_362/final)"}
附言:这样写会更习惯:
#include <iostream>
#include <vector>
#include <ctime>
using std::vector;
void process(vector<int> a, vector<int> b) {
const pair<int,int> dim = {1, 10000};
vector<int> barData(20000,0);
clock_t begin = clock();
for (int i = 0; i < dim.second; i++) {
for (int j = 0; j < i; j++) {
barData[j] = a[i];
barData[j] = b[i];
}
}
clock_t end = clock();
std::cout << double(end-begin)/CLOCKS_PER_SEC << '\n';
}
int main() {
vector<int> a(10000, 0), b(10000,0);
process(a,b);
return 0;
}
#包括
#包括
#包括
使用std::vector;
无效过程(向量a、向量b){
常量对dim={1,10000};
向量barData(20000,0);
时钟开始=时钟();
对于(int i=0;i std::难道这段代码没有任何作用,所以优化器正在启动…@EugeneSh:即使我做了其他事情,我也会得到同样的结果,我只是作为一个测试来尝试。你可以尝试一个更复杂的程序,同样的趋势会继续。@DrewDormann:你是什么意思?@DeepMitra我的意思是C编译器将无法编译这段代码,因为它会给出一个错误错误,大意是“这不是C代码”它的代码看起来是用不同的语言编写的。也许C++,包含<代码> >行>代码> MEX < /C>可以优化默认情况,我猜编译C++代码时你不会做。注意要注意的数据类型而不是丢弃。<代码> RAND < /COD>产生<代码>双< /Cord>矩阵,YO然后,您将以int
s的形式访问它们。类似地,您将创建mxINT64\u类的矩阵,并像访问int
s一样访问它们。
mex test.cpp -output foo
foo(rand(1,10000), rand(1,10000))
; ModuleID = 'test.cpp'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@_ZZ7processPiS_E3dim = internal constant [2 x i32] [i32 1, i32 10000], align 4
@.str = private unnamed_addr constant [4 x i8] c"%f\0A\00", align 1
; Function Attrs: uwtable
define void @_Z7processPiS_(i32* %a, i32* %b) #0 {
%1 = alloca i32*, align 8
%2 = alloca i32*, align 8
%barData = alloca [20000 x i32], align 16
%begin = alloca i64, align 8
%i = alloca i32, align 4
%j = alloca i32, align 4
%end = alloca i64, align 8
%elapsed_secs = alloca double, align 8
store i32* %a, i32** %1, align 8
store i32* %b, i32** %2, align 8
%3 = call i64 @clock() #3
store i64 %3, i64* %begin, align 8
store i32 0, i32* %i, align 4
br label %4
; <label>:4 ; preds = %34, %0
%5 = load i32* %i, align 4
%6 = load i32* getelementptr inbounds ([2 x i32]* @_ZZ7processPiS_E3dim, i32 0, i64 1), align 4
%7 = icmp slt i32 %5, %6
br i1 %7, label %8, label %37
; <label>:8 ; preds = %4
store i32 0, i32* %j, align 4
br label %9
; <label>:9 ; preds = %30, %8
%10 = load i32* %j, align 4
%11 = load i32* %i, align 4
%12 = icmp slt i32 %10, %11
br i1 %12, label %13, label %33
; <label>:13 ; preds = %9
%14 = load i32* %i, align 4
%15 = sext i32 %14 to i64
%16 = load i32** %1, align 8
%17 = getelementptr inbounds i32* %16, i64 %15
%18 = load i32* %17, align 4
%19 = load i32* %j, align 4
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds [20000 x i32]* %barData, i32 0, i64 %20
store i32 %18, i32* %21, align 4
%22 = load i32* %i, align 4
%23 = sext i32 %22 to i64
%24 = load i32** %2, align 8
%25 = getelementptr inbounds i32* %24, i64 %23
%26 = load i32* %25, align 4
%27 = load i32* %j, align 4
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds [20000 x i32]* %barData, i32 0, i64 %28
store i32 %26, i32* %29, align 4
br label %30
; <label>:30 ; preds = %13
%31 = load i32* %j, align 4
%32 = add nsw i32 %31, 1
store i32 %32, i32* %j, align 4
br label %9
; <label>:33 ; preds = %9
br label %34
; <label>:34 ; preds = %33
%35 = load i32* %i, align 4
%36 = add nsw i32 %35, 1
store i32 %36, i32* %i, align 4
br label %4
; <label>:37 ; preds = %4
%38 = call i64 @clock() #3
store i64 %38, i64* %end, align 8
%39 = load i64* %end, align 8
%40 = load i64* %begin, align 8
%41 = sub nsw i64 %39, %40
%42 = sitofp i64 %41 to double
%43 = fdiv double %42, 1.000000e+06
store double %43, double* %elapsed_secs, align 8
%44 = load double* %elapsed_secs, align 8
%45 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double %44)
ret void
}
; Function Attrs: nounwind
declare i64 @clock() #1
declare i32 @printf(i8*, ...) #2
; Function Attrs: uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%a = alloca [10000 x i32], align 16
%b = alloca [10000 x i32], align 16
store i32 0, i32* %1
%2 = getelementptr inbounds [10000 x i32]* %a, i32 0, i32 0
%3 = getelementptr inbounds [10000 x i32]* %b, i32 0, i32 0
call void @_Z7processPiS_(i32* %2, i32* %3)
ret i32 0
}
attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame- pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp- math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame- pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp- math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer- elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no- nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp- math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.6.2 (tags/RELEASE_362/final)"}
; ModuleID = 'test.cpp'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%f\0A\00", align 1
; Function Attrs: nounwind uwtable
define void @_Z7processPiS_(i32* nocapture readnone %a, i32* nocapture readnone %b) #0 {
%1 = tail call i64 @clock() #2
%2 = tail call i64 @clock() #2
%3 = sub nsw i64 %2, %1
%4 = sitofp i64 %3 to double
%5 = fdiv double %4, 1.000000e+06
%6 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double %5)
ret void
}
; Function Attrs: nounwind
declare i64 @clock() #1
; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #1
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = tail call i64 @clock() #2
%2 = tail call i64 @clock() #2
%3 = sub nsw i64 %2, %1
%4 = sitofp i64 %3 to double
%5 = fdiv double %4, 1.000000e+06
%6 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double %5) #2
ret i32 0
}
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame- pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft- float"="false" }
attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer- elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack- protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.6.2 (tags/RELEASE_362/final)"}
#include <iostream>
#include <vector>
#include <ctime>
using std::vector;
void process(vector<int> a, vector<int> b) {
const pair<int,int> dim = {1, 10000};
vector<int> barData(20000,0);
clock_t begin = clock();
for (int i = 0; i < dim.second; i++) {
for (int j = 0; j < i; j++) {
barData[j] = a[i];
barData[j] = b[i];
}
}
clock_t end = clock();
std::cout << double(end-begin)/CLOCKS_PER_SEC << '\n';
}
int main() {
vector<int> a(10000, 0), b(10000,0);
process(a,b);
return 0;
}