gpt4 book ai didi

c++ - Armadillo inplace_plus 明显慢于 "normal"plus 操作

转载 作者:行者123 更新时间:2023-11-28 02:38:27 26 4
gpt4 key购买 nike

我正在使用 Armadillo 4.500.0 编写程序,我发现像 s += v * v.t() * q; 这样的就地计算比等效的 s 慢得多= s + v * v.t() * q; 其中 svq 是适当大小的 vector 。

当我运行以下代码时,事实证明就地版本比其他版本慢很多倍,对于 500 个元素慢 ~480 倍(5.13 秒到 0.011 秒)并进行积极优化(-O3 或 -Ofast;Apple LLVM 版本 6.0 (clang-600.0.54))。

#include <iostream>
#include <armadillo>
#include <sys/time.h>

using namespace arma;
using namespace std;

#define N_ELEM 500
#define REP 10000

int main(int argc, const char * argv[]) {
timeval start;
timeval end;
double tInplace, tNormal;
vec s = randu<vec>(N_ELEM);
vec v = randu<vec>(N_ELEM);
vec q = randu<vec>(N_ELEM);

gettimeofday(&start, NULL);

for(int i = 0; i < REP; ++i) {
s += v * v.t() * q;
}

gettimeofday(&end, NULL);

tInplace = (end.tv_sec - start.tv_sec + ((end.tv_usec - start.tv_usec) / 1e6));

gettimeofday(&start, NULL);

for(int i = 0; i < REP; ++i) {
s = s + v * v.t() * q;
}

gettimeofday(&end, NULL);

tNormal = (end.tv_sec - start.tv_sec + ((end.tv_usec - start.tv_usec) / 1e6));

cout << "Inplace: " << tInplace << "; Normal: " << tNormal << " --> " << "Normal is " << tInplace / tNormal << " times faster" << endl;

return 0;
}

谁能解释为什么 inplace 运算符的性能如此糟糕,尽管它可以使用已经可用的内存,所以它不需要复制任何东西?

最佳答案

v.t() * q 括起来将解决问题:

for(int i = 0; i < REP; ++i) {
s += v * (v.t() * q);
}

使用括号强制计算顺序。表达式 (v.t() * q) 将计算为标量(技术上是 1x1 矩阵),然后用于乘以 v vector 。括号还将防止 v * v.t() 变成显式外积。

Armadillo 在使用 s = s + v * v.t() * q 表达式时可以自动解决这个问题,但它(目前)在使用 inplace 运算符时需要更多提示 +=

关于c++ - Armadillo inplace_plus 明显慢于 "normal"plus 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26766831/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com