- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我们正处于 porting our codebase 的过程中转到 Eigen 3.3(所有 32 字节对齐问题都是一项艰巨的任务)。然而,有几个地方的性能似乎受到了严重影响,这与预期相反(鉴于对 FMA 和 AVX 的额外支持,我期待一些加速......)。这些包括特征值分解和 matrix*matrix.transpose()*vector 产品。我已经编写了两个最小的工作示例来进行演示。
所有测试都在最新的 Arch Linux 系统上运行,使用 Intel Core i7-4930K CPU (3.40GHz),并使用 g++ 版本 6.2.1 编译。
使用 Eigen 3.3.0 进行简单的自伴随特征值分解所需的时间是使用 3.2.10 的两倍。
文件test_eigen_EVD.cpp
:
#define EIGEN_DONT_PARALLELIZE
#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#define SIZE 200
using namespace Eigen;
int main (int argc, char* argv[])
{
MatrixXf mat = MatrixXf::Random(SIZE,SIZE);
SelfAdjointEigenSolver<MatrixXf> eig;
for (int n = 0; n < 1000; ++n)
eig.compute (mat);
return 0;
}
测试结果:
eigen-3.2.10:
g++ -march=native -O2 -DNDEBUG -isystem eigen-3.2.10 test_eigen_EVD.cpp -o test_eigen_EVD && time ./test_eigen_EVD
real 0m5.136s
user 0m5.133s
sys 0m0.000s
Eigen 3.3.0:
g++ -march=native -O2 -DNDEBUG -isystem eigen-3.3.0 test_eigen_EVD.cpp -o test_eigen_EVD && time ./test_eigen_EVD
real 0m11.008s
user 0m11.007s
sys 0m0.000s
不确定是什么原因造成的,但如果有人能看到使用 Eigen 3.3 保持性能的方法,我很想知道!
这个特殊的例子在 Eigen 3.3.0 中花费了 200 倍的时间......
文件test_eigen_products.cpp
:
#define EIGEN_DONT_PARALLELIZE
#include <Eigen/Dense>
#define SIZE 200
using namespace Eigen;
int main (int argc, char* argv[])
{
MatrixXf mat = MatrixXf::Random(SIZE,SIZE);
VectorXf vec = VectorXf::Random(SIZE);
for (int n = 0; n < 50; ++n)
vec = mat * mat.transpose() * VectorXf::Random(SIZE);
return vec[0] == 0.0;
}
测试结果:
eigen-3.2.10:
g++ -march=native -O2 -DNDEBUG -isystem eigen-3.2.10 test_eigen_products.cpp -o test_eigen_products && time ./test_eigen_products
real 0m0.040s
user 0m0.037s
sys 0m0.000s
Eigen 3.3.0:
g++ -march=native -O2 -DNDEBUG -isystem eigen-3.3.0 test_eigen_products.cpp -o test_eigen_products && time ./test_eigen_products
real 0m8.112s
user 0m7.700s
sys 0m0.410s
像这样在循环中的行中添加括号:
vec = mat * ( mat.transpose() * VectorXf::Random(SIZE) );
有很大的不同,两个 Eigen 版本的性能都一样好(实际上 3.3.0 稍微好一点),并且比未加括号的 3.2.10 更快。所以有一个修复。不过,奇怪的是 3.3.0 会为此苦苦挣扎。
我不知道这是否是一个错误,但我认为值得报告,以防需要修复。或者也许我只是做错了......
任何想法表示赞赏。干杯,唐纳德。
作为pointed out by ggael ,如果使用 clang++
或 -O3
和 g++
编译,Eigen 3.3 中的 EVD 会更快。所以问题 1 已解决。
问题 2 并不是真正的问题,因为我可以用括号强制执行最有效的操作顺序。但只是为了完整性:在对这些操作的评估中似乎确实存在缺陷。 Eigen 是一款令人难以置信的软件,我认为这可能值得修复。这是 MWE 的修改版本,只是为了表明它不太可能与从循环中取出的第一个临时产品相关(至少据我所知):
#define EIGEN_DONT_PARALLELIZE
#include <Eigen/Dense>
#include <iostream>
#define SIZE 200
using namespace Eigen;
int main (int argc, char* argv[])
{
VectorXf vec (SIZE), vecsum (SIZE);
MatrixXf mat (SIZE,SIZE);
for (int n = 0; n < 50; ++n) {
mat = MatrixXf::Random(SIZE,SIZE);
vec = VectorXf::Random(SIZE);
vecsum += mat * mat.transpose() * VectorXf::Random(SIZE);
}
std::cout << vecsum.norm() << std::endl;
return 0;
}
在这个例子中,操作数都在循环内初始化,结果累积在 vecsum
中,因此编译器无法预先计算任何东西,或优化掉不必要的计算。这显示了完全相同的行为(这次使用 clang++ -O3
(版本 3.9.0)进行测试:
$ clang++ -march=native -O3 -DNDEBUG -isystem eigen-3.2.10 test_eigen_products.cpp -o test_eigen_products && time ./test_eigen_products
5467.82
real 0m0.060s
user 0m0.057s
sys 0m0.000s
$ clang++ -march=native -O3 -DNDEBUG -isystem eigen-3.3.0 test_eigen_products.cpp -o test_eigen_products && time ./test_eigen_products
5467.82
real 0m4.225s
user 0m3.873s
sys 0m0.350s
结果相同,但执行时间却大不相同。值得庆幸的是,这很容易通过在正确的位置放置括号来解决,但在 Eigen 3.3 的操作评估中似乎确实存在回归。在 mat.transpose() * VectorXf::Random(SIZE)
部分加上括号,两个 Eigen 版本的执行时间都减少到 0.020 秒左右(因此 Eigen 3.2.10 显然也有利于此案件)。至少这意味着我们可以继续从 Eigen 获得出色的性能!
与此同时,我会接受 ggael 的回答,这是我继续前进所需要知道的一切。
最佳答案
对于 EVD,我无法用 clang 重现。使用 gcc,您需要 -O3
来避免内联问题。然后,对于这两个编译器,Eigen 3.3 将提供 33% 的加速。
编辑 我之前关于matrix*matrix*vector
产品的回答是错误的。这是 Eigen 3.3.0 的一个缺点,将在 Eigen 3.3.1 中修复。作为记录,我把我之前的分析留在这里,它仍然部分有效:
As you noticed you should really add the parenthesis to perform two
matrix*vector
products instead of a bigmatrix*matrix
product. Then the speed difference is easily explained by the fact that in 3.2, the nestedmatrix*matrix
product is immediately evaluated (at nesting time), whereas in 3.3 it is evaluated at evaluation time, that is inoperator=
. This means that in 3.2, the loop is equivalent to:for (int n = 0; n < 50; ++n) {
MatrixXf tmp = mat * mat.transpose();
vec = tmp * VectorXf::Random(SIZE);
}and thus the compiler can move
tmp
out of the loop. Production code should not rely on the compiler for this kind of task and rather explicitly moves constant expression outside loops.
这是真的,除了在实践中编译器不够聪明,无法将临时变量移出循环。
关于c++ - Eigen 3.3.0 与 3.2.10 的性能回归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40805386/
[在此处输入图像描述][1]我正在努力弄清楚回归是否是我需要走的路线,以便解决我当前使用 Python 的挑战。这是我的场景: 我有一个 195 行 x 25 列的 Pandas Dataframe
我想训练回归模型(不是分类),其输出是连续数字。 假设我有输入变量 X,其范围在 -70 到 70 之间。我有输出变量 Y,其范围在 -5 到 5 之间。X 有 39 个特征,Y 有 16 个特征,每
我想使用神经网络逼近 sinc 函数。这是我的代码: import tensorflow as tf from keras.layers import Dense from keras.models
我对 postgres 表做了一些更改,我想将其恢复到以前的状态。没有数据库的备份。有办法吗?比如,postgres 会自动拍摄快照并将其存储在某个地方,还是原始数据会永远丢失? 最佳答案 默认情况下
我有大约 100 个 7x7 因变量矩阵(所以有 49 个因变量)。我的自变量是时间。我正在做一个物理项目,我应该通过求解 ODE 得到一个矩阵函数(矩阵的每个元素都是时间的函数)。我使用了 nump
我之前曾被告知——出于完全合理的原因——当结果变量为二元变量时(即是/否、真/假、赢/输等),不应运行 OLS 回归。但是,我经常阅读经济学/其他社会科学方面的论文,其中研究人员对二元变量运行 OLS
您好,我正在使用生命线包进行 Cox 回归。我想检查非二元分类变量的影响。有内置的方法吗?或者我应该将每个类别因子转换为一个数字?或者,在生命线中使用 kmf fitter,是否可以对每个因素执行此操
作为后续 this question ,我拟合了具有定量和定性解释变量之间相互作用的多元 Logistic 回归。 MWE如下: Type |z|) (Intercept) -0.65518
我想在单个动物园对象中的多对数据系列上使用 lm 执行滚动回归。 虽然我能够通过以下代码对动物园对象中的一对数据系列执行滚动回归: FunLm seat time(seat) seat fm
是否有一种简单的方法可以在 R 中拟合多元回归,其中因变量根据 Skellam distribution 分布? (两个泊松分布计数之间的差异)?比如: myskellam <- glm(A ~ B
包含各种特征和回归目标(称为 qval)的数据集用于训练 XGBoost 回归器。该值 qval 介于 0 和 1 之间,应具有以下分布: 到目前为止,还不错。但是,当我使用 xgb.save_mod
这有效: felm(y ~ x1 + x2 | fe1 + fe2 | 0 | , data = data) 我想要: fixedeffects = "fe1 + fe2" felm(y ~ x1
这有效: felm(y ~ x1 + x2 | fe1 + fe2 | 0 | , data = data) 我想要: fixedeffects = "fe1 + fe2" felm(y ~ x1
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我刚刚开始使用 R 进行统计分析,而且我还在学习。我在 R 中创建循环时遇到问题。我有以下案例,我想知道是否有人可以帮助我。对我来说,这似乎是不可能的,但对你们中的一些人来说,这只是小菜一碟。我有不同
是否可以在 sklearn 中使用或不使用(即仅使用截距)预测器来运行回归(例如逻辑回归)?这似乎是一个相当标准的类型分析,也许这些信息已经在输出中可用。 我发现的唯一相关的东西是sklearn.sv
假设我对一些倾斜的数据分布执行 DNN 回归任务。现在我使用平均绝对误差作为损失函数。 机器学习中的所有典型方法都是最小化平均损失,但对于倾斜来说这是不恰当的。从实际角度来看,最好尽量减少中值损失。我
我正在对公寓特征进行线性回归分析,然后预测公寓的价格。目前,我已经收集了我所在城市 13000 套公寓的特征。我有 23-25 个特征,我不确定在公寓价格预测中拥有如此多的特征是否正常。 我有以下功能
我是 ML 新手,对 catboost 有疑问。所以,我想预测函数值(例如 cos | sin 等)。我回顾了一切,但我的预测始终是直线 是否可能,如果可能,我该如何解决我的问题 我很高兴收到任何评论
我目前已经为二进制类实现了概率(至少我这么认为)。现在我想扩展这种回归方法,并尝试将其用于波士顿数据集。不幸的是,我的算法似乎被卡住了,我当前运行的代码如下所示: from sklearn impor
我是一名优秀的程序员,十分优秀!