前言
前几天,我问了关于Matlab和Python的性能的问题。 (performance :材料vs python )。 Matlab比Python快,特别是在meshgrid上,有人指出讨论这个问题时应该用Python的包装器来调用我的C,我很惊讶。
在这样做的过程中,Matlab再次惊讶于矩阵的组装和计算比c还快。 有一个稍微大一点的代码,正在研究矩阵向量乘法。 大代码在多个实例中执行这样的乘法。 总体上,c的代码比Matlab快得多,但由于Matlab的函数调用有开销等原因,Matlab使用矩阵向量乘法(
结果
下表显示了组装内核矩阵所需的时间与矩阵和向量相乘所需的时间的比较。 结果被编译为矩阵大小NN,其中n在10,000到40,000之间变化。 哪个不是很大。 但是,有趣的是,通过Mat得到的n越大,性能越好。 Matlab总时间加快3.8倍至5.8倍。 另外,在矩阵的组装和计算中
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| n=10,000 assemblycomputationtotal |
|MATLAB 0.3387 0.031 0.3697 |
|C 1.15 0.24 1.4 |
|Times faster 3.8 |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| n=20,000 assemblycomputationtotal |
|MATLAB 1.089 0.0977 1.187 |
|C 5.1 1.03 6.13 |
|Times faster 5.2 |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| n=40,000 assemblycomputationtotal |
|MATLAB 4.31 0.348 4.655 |
|C 23.25 3.91 27.16 |
|Times faster 5.8 |
请参见------------------------------------------------------- -
问题
C那么有更快的方法吗? 我错过了什么吗? 我知道C使用for循环,但我理解Matlab也会在meshgrid上做同样的事情。
代码片段
Matlab代码:
% % getinputdatafromdatafiles-----------------getinputdatafromdatafiles ----------------------------------- -
% Read data from input file
DATA=load(input/input.txt );
location=data(:1:2;
charges=data (:3: end );
n=length(location );
m=size(Charges,2 );
% % exactmatrixvectorproduct-----------------exactmatrixvectorproduct 把--------------------------------------------------------------------------- -
kex1=ex1;
tic
q=kex1.Kernel_2d(location,location );
frintf((nassemblytime:%f )、toc );
tic
potential_exact=Q * charges;
计算时间: % f (n ),toc );
类(使用消息网格) :
类def ex1
方法
function[Kernel]=Kernel_2d(obj,x,y ) ) ) ) ) )。
[i1,J1 ]=mesh grid (y 65:1 ),x 65:1 );
[i2,J2 ]=mesh grid (y 65:2 ),x 65:2 );
kernel=sqrt((I1-J1 ).^2) I2-J2 ).^2);
结束
结束
结束
c代码:
编辑
使用标记为以下的make文件进行编译:
CC=g
cflags=-c-fopen MP-w-wall-dn debug-O3-March=native-ffast-math-f finite-math-only-I header/- I/usr
LDFLAGS=-g -fopenmp
LIB_PATH=
sources text=src/read _ location _ charges.CPP
SOURCESF=examples/matvec.cpp
objectsf=$ (sourcesf :CPP=.o ) sourcestext3360.CPP=.o ) ) ) ) ) ) ) ) )。
EXECUTABLEF=./exec/mykernel
myKernel:$(sourcesf ) $(SOURCESTEXT ) $(EXECUTABLEF ) ) ) ) ) ) ) ) )。
$(executablef(:$ ) objectsf ) ) ) ) ) ) ) )。
$(cc ) $(LDFLAGS ) $(kernel ) ) ($(INDEX ) objectsf(-o$@$ ) lib_path ) ) ) )。
. cpp.o:
$(cc ) $ ) $(CFLAGS ) $(kernel ) $(INDEX ) $ -o $@
`
# include'environment.hpp '
using namespace std;
using namespace Eigen;
class ex1
{
公共:
void kernel _ 2d (constunsignedlongm,double* x,const unsigned long N,double* y,MatrixXd kernel ) )。
kernel=matrixxd:3360zero(m,n );
for (无符号长I=0; I
for (无符号龙j=0; j
doublex=(x[0*nI]-y[0*nj];
doubley=(x[1*nI]-y[1*nj];
Kernel(I,j )=sqrt ) (x*x ) (Y*Y );
}
}
}
(;
int main () )
{
/*把input-------------------------------------------------------------------- -
unsigned long N=40000; unsigned m=1;
双*字符; 双*定位;
charges=new double[N * m] (; location=new double[N * 2] (;
clock_t start; clock_t end;
double exactAssemblyTime; double exactComputationTime;
read _ location _ charges (' input/test _ input.txt ',n,location,m,charges );
MatrixxdCharges_=map(Charges,n,m );
MatrixXd Q;
ex1 Kex1;
请参阅/* process--------------------------------------
//矩阵组件
start=clock (;
kex1.kernel_2d(n,location,n,location,q );
end=clock (;
exactassemblytime=double (end-start )/double (clocks _ per _ sec );
//Computation
start=clock (;
MatrixXd QH=Q * charges_;
end=clock (;
exactcomputationtime=double (end-start )/double (clocks _ per _ sec );
cout endl ' assembly time : ' exactassemblytimeendl;
cout endl ' computation time : ' exactcomputationtimeendl;
//Clean up
delete []charges;
delete [ ]位置;
返回0;
}