我正在尝试将之前用Python编写的一些代码转换为C++,目前我正在测试xtensor以查看它是否比numpy更快地完成我需要的任务。
我的其中一个函数接受一个方阵d和一个标量alpha,并执行逐元素操作alpha /(alpha + d)
。背景:此函数用于测试哪个alpha
值最好,因此它在循环中使用,其中d
始终相同,但alpha
不同。
以下所有时间尺度都是运行该函数100次的平均值。
在numpy中,这需要大约0.27秒,并且代码如下:
def kfun(d,alpha):
k = alpha /(d+alpha)
return k
但是xtensor需要大约0.36秒的时间,代码如下:
xt::xtensor<double,2> xk(xt::xtensor<double,2> d, double alpha){
return alpha/(alpha+d);
}
我也尝试过使用
std::vector
来实现,但这不是我长期想要使用的,尽管它只花费了 0.22 秒。std::vector<std::vector<double>> kloops(std::vector<std::vector<double>> d, double alpha, int d_size){
for (int i = 0; i<d_size; i++){
for (int j = 0; j<d_size; j++){
d[i][j] = alpha/(alpha + d[i][j]);
}
}
return d;
}
我注意到xtensor中的operator/
使用了“惰性广播”,也许有一种方法可以使它立即执行吗?
编辑:
在Python中,使用以下方式调用该函数,并使用“time”包计时。
t0 = time.time()
for i in range(100):
kk = k(dsquared,alpha_squared)
print(time.time()-t0)
在C++中,我调用函数如下,并使用计时器chronos进行计时:
//d is saved as a 1D npy file, an artefact from old code
auto sd2 = xt::load_npy<double>("/path/to/d.npy");
shape = {7084, 7084};
xt::xtensor<double, 2> xd2(shape);
for (int i = 0; i<7084;i++){
for (int j=0; j<7084;j++){
xd2(i,j) = (sd2(i*7084+j));
}
}
auto start = std::chrono::steady_clock::now();
for (int i = 0;i<10;i++){
matrix<double> kk = kfun(xd2,4000*4000,7084);
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "k takes: " << elapsed_seconds.count() << "\n";
如果你想运行这段代码,我建议使用
xd2
作为一种对称的7084x7084随机矩阵,对角线上为零。该函数的输出是一个名为
k
的矩阵,然后将在其他函数中使用,但我仍需要保持d
不变,因为它稍后会被重复使用。要运行我的C++代码,可以在终端中使用以下命令行:
cd "/path/to/src/" && g++ -mavx2 -ffast-math -DXTENSOR_USE_XSIMD -O3 ccode.cpp -o ccode -I/path/to/xtensorinclude && "/path/to/src/"ccode
提前感谢!
d_size
选项已经超出了我的屏幕,所以我没有注意到它,并且假设您可能有一个打字错误。对于向量示例,您有一些未定义的d2
,但是您已经纠正了这个问题,所以一切都很好! - Tom de Geus