在犰狳库中引用向量的最快方法
Posted
技术标签:
【中文标题】在犰狳库中引用向量的最快方法【英文标题】:fastest way to refer to vector in Armadillo library 【发布时间】:2013-09-17 20:29:24 【问题描述】:我将犰狳用于线性代数。我设置了一个相当大的向量(至少 35000000 个元素)。我有另一个长度为大向量一半的向量。我正在使用 fftw 对大向量进行傅里叶变换,但前半部分数据是从小向量复制的,如下所示
#include <armadillo>
#include <iostream>
#include <iomanip>
#include <fstream>
#include "fftw3.h"
using namespace std;
using namespace arma;
int main(void)
arma::Col<double> v1, v2;
v1.resize(35000000);
v2.resize(17500000);
// initialize v2
for (int i=0; i<4096; i++) // repeat 4096 times
v1.rows(0, 17500000) = v2;
fftw_complex* in = reinterpret_cast<fftw_complex*>(v1.colptr(0));
fftw_plan plan = fftw_plan_dft_1d(35000000, in, in, FFTW_FORWARD, FFTW_MEASURE);
v2 = v1.rows(0, 175000000);
这段代码非常慢,因为我们需要将元素从 v2 复制到 v1 并向后复制。无论如何让 v1 的元素引用 v2 而不是副本?
【问题讨论】:
也许看看sub-matrix views? 复制 v1.rows 后是否更改 v2? 其实 v2 是我存储结果的地方,但我会在计算中使用 v1,只有前半部分会保存回 v2。 v2更新后,会复制到v1的前半部分,重复同样的过程。 【参考方案1】:不完全确定您要达到的目标,但是 您可以通过.memptr() 函数获取指向向量(或矩阵)使用的内存的指针。然后可以使用这个指针和一个偏移量来创建一个新的向量(或矩阵),它通过专用的vector constructors 和matrix constructors 使用外部/辅助内存。
例如:
vec v1(35000000);
vec v2(v1.memptr(), 17500000, false); // v2 will now share memory with v1
顺便说一句,除非您真的想保留现有数据,否则不要将 .resize() 函数与 Armadillo 向量和矩阵一起使用。请改用.set_size(),这样更快。
【讨论】:
看起来和我要找的差不多。但据我了解,现在 v2 指向 v1 的前半部分,所以 v1 中的前半部分元素与 v2 共享内存,对吗?那么如果我在v1中修改任何索引小于17500000的元素,在v2中对应的元素是否也会被改变? 您好,mtall,感谢您的建议。这真的是我要找的。但是当我对矩阵使用类似的技术时,我遇到了一个新问题。例如,我有一个 5x5 矩阵 M1,我想要一个 M2 矩阵,它是 3x5 共享与 M1 相同的内存,所以 M2 将引用前 3 行。我做了和你一样的事情,比如 mat m1(5,5);垫 m2(m1.memptr(),3,5,假,假);但这将使 m2 改为引用前几列。我认为这是由于面向列的问题。我该如何解决? 犰狳矩阵中的内存布局遵循 BLAS 和 LAPACK。换句话说,数据是逐列存储的。因此,访问一行中的元素会相对低效。我建议您修改您的算法以处理整列而不是整行。矩阵转置在这里可以提供帮助(例如,对每一列进行处理,然后转置矩阵以逐行获取答案)。 感谢您的建议。修改代码是一件很头疼的事,这只是几千行代码的一小部分:( 还有一个问题。如果我写 vec v2(v1.memptr(), 17500000, false);代码没有任何问题。但是如果我做 vec v2; v2=vec(v1.memptr(), 17500000, 假);它确实可以编译,但不会引用 v1。我想要第二种情况是什么原因,有什么解决方法吗?谢谢以上是关于在犰狳库中引用向量的最快方法的主要内容,如果未能解决你的问题,请参考以下文章