通过内存管理实现高效编码

时间:2015-09-30 06:46:00

标签: c++ memory-management

我最近从matlab切换到了c ++,以便更快地运行模拟,但它仍然运行缓慢。我非常肯定在内存使用方面有很多改进。

考虑以下代码,它显示了我在模拟中使用的两个数组/向量声明的示例。

一个具有已知固定长度(array01)和另一个具有未知长度(array02)的运行期间会发生变化。

这里的问题是在内存使用和性能方面声明变量(对于两种数组类型)的最佳/适当/有效方式。

# include <iostream>
# include <vector>
# include <ctime>
# include <algorithm>
using namespace std;

const int n = 1000;
const int m= 100000;
int main()
{
    srand((unsigned)time(NULL));
    vector <double> array02;
    vector <vector<double>> Array01(n,m);
    for (unsigned int i=0; i<n; i++)
    {
        for (unsigned int j=0; j<m;j++)
        {
             array02.clear();
             rr = rand() % 10;
             for (unsigned int l = 0 ; l<rr <l++)
             {
                  array02.pushback(l);
             }
             // perform some calculation with array01 and array02
         }           
     }
}

3 个答案:

答案 0 :(得分:2)

您应该考虑使用Matrix成员函数定义您自己的void resize(unsigned width, unsigned height),以及double get(unsigned i, unsigned j)内联成员函数和/或{{1}内联成员函数(两者都给出 M i,j 元素)。矩阵内部数据可以是一维数组或双精度矢量。使用矢量矢量(所有相同大小)并不是表示矩阵的最佳(或最快)方式。

double& at(unsigned i, unsigned j)

另请阅读rule of five

你也可以尝试scilab(它是免费软件)。它类似于Matlab,可能有不同的性能。不要忘记使用最新版本。

BTW,有大量现有的C ++数值库处理矩阵。考虑使用其中之一。如果性能至关重要,请不要忘记在调试代码后让编译器优化代码。

假设您使用的是Linux(我推荐用于数值计算;大多数超级计算机运行Linux都很重要),在调试阶段使用class Matrix { std::vector<double> data; unsigned width, height; public: Matrix() : data(), width(0), height(0) {}; ~Matrix() = default; /// etc..., see rule of five void resize(unsigned w, unsigned h) { data.resize(w*h); width = w; height = h; } double get(unsigned i, unsigned j) const { assert(i<width && j<height); return data[i*width+j]; } double& at(unsigned i, unsigned j) { assert(i<width && j<height); return data[i*width+j]; } }; // end class Matrix 进行编译,然后在基准测试期间使用g++ -std=c++11 -Wall -Wextra -g。不要忘记profile,并记住过早优化是邪恶的(首先需要让你的程序正确)。

您甚至可能花费数周,数月甚至数年的时间来使用OpenMPOpenCLMPIpthreads或{{3}等技术} std::thread(这是一个困难的主题,你需要多年才能掌握)。

如果你的矩阵很大,和/或有其他属性(parallelizationsparsetriangular等...),掌握了许多数学和计算机科学知识改善表现。你可以在那里攻读博士学位,并将一生都花在这个主题上。请访问您的大学图书馆,阅读symmetricnumerical analysis上的一些图书。

对于随机数linear algebra,您会C++11; BTW使用C ++ 11或C ++ 14,而不是早期版本的C ++。

另请阅读<random>和一本关于http://floating-point-gui.de/的好书。

PS。我没有要求任何关于数值计算的专业知识。我更喜欢象征性计算。

答案 1 :(得分:2)

首先不要尝试重新发明轮子:)尝试使用一些经过大量优化的数值库,例如

  • 英特尔MKL(适用于英特尔和兼容处理器的最快且最常用的数学库)
  • LAPACK ++(高性能线性代数库)
  • 提升(不仅是数字,还解决了几乎所有问题)

第二:如果您需要一个非常简单的程序矩阵,请使用vector[i + width * j]表示法。它更快,因为你节省了额外的内存分配。

您的示例没有事件编译。我试着改写一下:

#include <vector>
#include <ctime>

int main()
{
    const int rowCount = 1000;
    const int columnCount = 1000;

    srand(time(nullptr));

    // Declare matrix
    std::vector<double> matrix;

    // Preallocate elemts (faster insertion later)
    matrix.reserve(rowCount * columnCount);

    // Insert elements
    for (size_t i = 0; i < rowCount * columnCount; ++i) {
        matrix.push_back(rand() % 10);
    }

    // perform some calculation with matrix
    // For example this is a matrix element at matrix[1, 3]:
    double element_1_3 = matrix[3 + 1 * rowCount];

    return EXIT_SUCCESS;
}

现在速度取决于rand()(这很慢)。

答案 2 :(得分:1)

正如人们所说:

  • 首选1d数组而不是2d数组作为矩阵。
  • 不要重新发明轮子,使用现有的库:我认为从您的代码判断Eigen library是最适合您的套件。它还生成非常非常优化的代码,因为它尽可能使用C ++模板静态计算。