有效地对均匀随机矩阵进行采样

时间:2016-02-21 08:53:58

标签: c++ matrix random

我需要采样一个巨大的随机矩阵,其大小为499 x 15500,即7734500个元素。因此,我希望抽样程序尽可能高效。目前,在cpp文件中我这样做:

std::random_device rd; // seed generator

std::mt19937_64 generator{rd()}; // generator initialized with seed from rd


std::uniform_int_distribution<> initialize(unsigned long long int modulus)
{
    std::uniform_int_distribution<> unifDist{0, (int)(modulus-1)};
    return unifDist;
}


Matrix<unsigned int> uniformRandomMatrix
    (unsigned int rows, unsigned int columns, unsigned long long int modulus)
{
    std::uniform_int_distribution<> dist = initialize(modulus);

    // Declare and allocate the matrix
    Matrix<unsigned int> matrix(rows, columns);
    // this constructor just does a resize on a std::vector

    // Fill the matrix with random elements
    for(unsigned int i = 0; i < rows; ++i)
    {
        for(unsigned int j = 0; j < columns; ++j)
        {
            matrix.setElementAt(i, j, dist(generator));
            // setElementAt just does matrix[somePosition] = newElement
        }
    }

    return matrix;
}

请注意,Matrix实现为1D std::vector以提高效率。

我能做得比这更好吗?现在,对这个庞大的矩阵进行采样大约需要0.16秒。

使用std::vector::data

进行编辑

新方法是这样的:我在Matrix类中添加了一个方法

inline std::vector<T> exposeVector()
{
    return matrix;   // 'matrix' is the name of the private std::vector
}

然后采样制服Matrix

Matrix<unsigned int> uniformRandomMatrix
    (unsigned int rows, unsigned int columns, unsigned long long int modulus)
{
    std::uniform_int_distribution<> dist = initialize(modulus);

    // Declare and allocate the matrix
    Matrix<unsigned int> matrix(rows, columns);

    std::vector<unsigned int> v = matrix.exposeVector();
    unsigned int* p = v.data();

    for(unsigned int i = 0 ; i < rows*columns ; ++i)
    {
        *p = dist(generator);
        ++p;
    }

    return matrix;
}

一切似乎都运转良好,但我在表现方面没有获得任何好处。

1 个答案:

答案 0 :(得分:0)

在我看来,这是一个非常广泛的问题,但我会尝试给你一些指示:

  • 首先,可能最明显的事情是在多个线程std::thred
  • 中执行此操作
  • 如果您的Matrix是派生类,并且您的setElementAt是虚拟的,那么由于vtable解析它非常昂贵。摆脱它(见下一行)
  • 通常编译器已经做了很多优化,但您仍然可以通过公开vector::data并迭代为单个数组for(int i = 0; i < rows*cols; i++); data[i] = random或尝试std::generate来尝试最小化函数/方法调用