- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经开始使用 Rcpp。我很喜欢。我对编程相当陌生。我有一个关于内存使用的问题。下面是一个可重现的问题:
library(RcppArmadillo)
library(inline)
code <- "
Rcpp::NumericVector input_(input);
arma::cube disturb(input_.begin(), 2, 2, 50000000, false);
return wrap(2);
"
Test <- cxxfunction(signature(input = "numeric"), plugin = "RcppArmadillo", body = code)
input <- array(rnorm(2 * 2 * 50000000), dim = c(2, 2, 50000000))
Test(input)
最佳答案
新版 Armadillo (5.300)后编辑
在 StackOverflow 上的这个初步问答之后,Conrad Sanderson 和我就这个问题进行了一些电子邮件讨论。按照设计,arma::cube
对象创建 arma::mat
对于 cube
的每个切片(第三维) .这是在创建 cube
期间完成的。 ,即使数据是从现有内存复制的(如原始问题)。由于这并不总是需要,我建议应该有一个选项来禁用切片的矩阵预分配。从当前版本的 Armadillo (5.300.4) 开始,现在有了。这可以从 CRAN 安装。
示例代码:
library(RcppArmadillo)
library(inline)
code <- "
Rcpp::NumericVector input_(input);
arma::cube disturb(input_.begin(), 2, 2, 50000000, false, true, false);
return wrap(2);
"
Test <- cxxfunction(signature(input = "numeric"), plugin = "RcppArmadillo", body = code)
input <- array(rnorm(2 * 2 * 50000000), dim = c(2, 2, 50000000))
Test(input)
cube
现在使用
arma::cube disturb(input.begin(), 2, 2, 50000000, false, true, false);
调用构造函数.最后
false
这是新的
prealloc_mat
参数决定是否预先分配矩阵。
slice
方法在
cube
上仍然可以正常工作没有预先分配的矩阵 - 矩阵将按需分配。但是,如果您直接访问
mat_ptrs
成员(member)
cube
它将充满
NULL
指针。
The help has also been updated.
library("RcppArmadillo")
library("inline")
code <- "
Rcpp::NumericVector input_(input);
IntegerVector dim = input_.attr(\"dim\");
arma::cube disturb(input_.begin(), dim[0], dim[1], dim[2], false);
disturb[0, 0, 0] = 45;
return wrap(2);
"
Test <- cxxfunction(signature(input = "numeric"), plugin = "RcppArmadillo", body = code)
input <- array(0, c(1e7, 2, 2))
Test(input)
# no change in memory usage
dim(input) <- c(2, 1e7, 2)
gc()
Test(input)
# no change in memory usage
dim(input) <- c(2, 2, 1e7)
gc()
Test(input)
# spike in memory usage
dim(input) <- c(20, 2, 1e6)
gc()
Test(input)
# no change in memory usage
Aramadillo
的方式有关。库已实现(或可能是
RcppArmadillo
)。这当然似乎不是你做错了什么。
arma::cube
期间分配 RAM .在
Cube_meat.hpp
,在
create_mat
方法,有如下代码:
if(n_slices <= Cube_prealloc::mat_ptrs_size)
{
access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
}
else
{
access::rw(mat_ptrs) = new(std::nothrow) const Mat<eT>*[n_slices];
arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" );
}
}
Cube_prealloc::mat_ptrs_size
似乎是 4,所以对于任何超过 4 个切片的数组来说,这实际上是一个问题。
#include <iostream>
#include <armadillo>
#include <unistd.h>
#include <ios>
#include <fstream>
#include <string>
//////////////////////////////////////////////////////////////////////////////
//
// process_mem_usage(double &, double &) - takes two doubles by reference,
// attempts to read the system-dependent data for a process' virtual memory
// size and resident set size, and return the results in KB.
//
// On failure, returns 0.0, 0.0
void process_mem_usage(double& vm_usage, double& resident_set)
{
using std::ios_base;
using std::ifstream;
using std::string;
vm_usage = 0.0;
resident_set = 0.0;
// 'file' stat seems to give the most reliable results
//
ifstream stat_stream("/proc/self/stat",ios_base::in);
// dummy vars for leading entries in stat that we don't care about
//
string pid, comm, state, ppid, pgrp, session, tty_nr;
string tpgid, flags, minflt, cminflt, majflt, cmajflt;
string utime, stime, cutime, cstime, priority, nice;
string O, itrealvalue, starttime;
// the two fields we want
//
unsigned long vsize;
long rss;
stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
>> utime >> stime >> cutime >> cstime >> priority >> nice
>> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
stat_stream.close();
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
vm_usage = vsize / 1024.0;
resident_set = rss * page_size_kb;
}
using namespace std;
using namespace arma;
void test_cube(double* numvec, int dim1, int dim2, int dim3) {
double vm, rss;
cout << "Press enter to continue";
cin.get();
process_mem_usage(vm, rss);
cout << "Before:- VM: " << vm << "; RSS: " << rss << endl;
cout << "cube c1(numvec, " << dim1 << ", " << dim2 << ", " << dim3 << ", false)" << endl;
cube c1(numvec, dim1, dim2, dim3, false);
process_mem_usage(vm, rss);
cout << "After:- VM: " << vm << "; RSS: " << rss << endl << endl;
}
int
main(int argc, char** argv)
{
double* numvec = new double[40000000];
test_cube(numvec, 10000000, 2, 2);
test_cube(numvec, 2, 10000000, 2);
test_cube(numvec, 2, 2, 1000000);
test_cube(numvec, 2, 2, 2000000);
test_cube(numvec, 4, 2, 2000000);
test_cube(numvec, 2, 4, 2000000);
test_cube(numvec, 4, 4, 2000000);
test_cube(numvec, 2, 2, 10000000);
cout << "Press enter to finish";
cin.get();
return 0;
}
create_mat
上面的代码,一个
arma::mat
是为
创建的每个切片的立方体。在我的 64 位机器上,这会导致每个切片产生 184 字节的开销。对于具有 5e7 个切片的多维数据集,这相当于 8.6 GiB 的开销,即使基础数字数据仅占用 1.5 GiB。我已经给康拉德·桑德森发了电子邮件,询问这是否是 Armadillo 工作方式的基础或可以改变,但现在看来你肯定想要你的
slice
如果可能的话,维度(第三个)是三个中最小的一个。还值得注意的是,这适用于
全部
cube
s,而不仅仅是那些从现有内存中创建的。使用
arma::cube(dim1, dim2, dim3)
构造函数导致相同的内存使用。
关于c++ - Rcpp Armadillo : Issue with memory usage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31439134/
在许多网站上,他们谈论 Armadillo +其他东西。它们是什么意思? 我以以下形式使用 Armadillo 库 #include 在 Linux 环境中。 在这个网站上 http://nghia
尽管成功捕获了异常,但是运行以下代码仍然会生成一条错误消息,该消息将发送到stdout(不是stderr): Mat matrix_quantiles(const vector & quantiles
我需要将 Armadillo (当前版本为 5.100.1)作为 $HOME 中的本地库(集群应用程序,不能安装在每个计算节点上,但 $HOME 是共享文件夹)。我正在使用 cmake 来管理应用程序
如何在 Armadillo C++ 中获取非零位置(索引)数组和稀疏矩阵的值? 到目前为止,我可以轻松地构造一个具有一组位置(作为 umat 对象)和值(作为 vec 对象)的稀疏矩阵: // bat
NLopt 目标函数如下所示: double myfunc(const std::vector &x, std::vector &grad, void *my_func_data) x 是被优化的数据
我想将一个 numpy 数组发送到 Armadillo (C++) 并从 C++ 程序输出一个 numpy 数组。我没有在网上找到任何教程。有人可以指点我如何做到这一点吗? 最佳答案 您可以依靠 cy
我正在尝试使用 OpenMP 并行化一个 for 循环,它对 Armadillo 矩阵求和。我有以下代码: #include #include int main() { arma:
尽管已成功捕获异常,但运行以下代码仍会产生一条错误消息,该消息会转到 stdout(而非 stderr): Mat matrix_quantiles(const vector & quantiles,
我喜欢使用 Armadillo Linear Algebra Library .当将 Octave .m 文件移植到 C++ 时,它变得非常好,尤其是当您必须使用特征方法时。 然而,当我不得不从我的原
如何实现一个简单的合并函数来合并两个矩阵,每个矩阵都有两列和一个公共(public)列 x使用 Armadillo ?换句话说,我想要一个函数 my_merge_cpp(mat1, mat2)这将使用
我正在尝试使用 Armadillo 将由整数(即 arma::Mat )组成的矩阵分解为特征值和特征向量 但是,无论我将什么作为输入矩阵和输出 vector/矩阵类型,它总是会给我编译错误 当我将输入
我有一种方法可以在使用 Armadillo 的原子中使用脚本编译c++文件?我找不到任何与此相关的信息。 我已经安装了 Armadillo ,并尝试使用原子脚本编写一些基本代码: #include
我在 cygwin64(或 minGW)下使用 Armadillo 包(v.7.300.1)生成一个随机矩阵: #include int main(){ arma::mat(3,3, arma::
我目前正在 Visual Studio 环境中使用 Armadillo 在 BeagleBone Black 上进行交叉编译,以将 MATLAB 代码转换为 C++。 这是一个信号处理项目,所以我需要
我是 Armadillo 的新手。我有以下代码,我认为它效率低下。有什么建议可以提高内存效率和/或速度吗?关注armadillo docs和 Rcpp gallery ,我无法获得 .colptr的,
如何提高 Armadillo 复杂矩阵乘法结果的精度。它近似于小数点后 4 位 [这是结果的一个示例 (35.9682,-150.246) ] 但我想要至少 8 位小数的精度。谢谢 最佳答案 因为你似
假设我有一个稀疏矩阵。我将其定义为以下 CSV 格式: 行、列、值 1,1,5 1,2,10 在这种情况下,点 (1,1) 等于 5,点 (1,2) 等于 10。 从这种格式(假设有数千或数十万行)创
我在一个项目中使用 Armadillo ,总的来说它运行良好。该项目是基于 Xcode 的,到目前为止,我设法让它工作的唯一方法是(添加/usr/include/的 header 搜索路径似乎不起作用
在 C++ 中对 vector 或矩阵执行模运算符的最佳方法是什么 Armadillo ? vector 和矩阵类重载 % 运算符以执行逐元素乘法。尝试使用它会产生 invalid operands
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Precision of multiplication by 1.0 and int float conv
我是一名优秀的程序员,十分优秀!