C++ 在c+中复制大型容器的最佳方法+;

C++ 在c+中复制大型容器的最佳方法+;,c++,performance,C++,Performance,我对复制大型容器的最佳方式感兴趣。假设有一个向量容器,它存储例如60.000.000个条目(可能是长双倍)或更多的值。现在,如果要求解ODE(常微分方程),则有必要(根据使用的算法)复制用于计算的旧值,以更新新值。以下(想象的)例子: 如有任何评论,我们将不胜感激。Tobi第一个片段基本上是这样的 for(i=0; i<iMax, ++i) { vector<long double> YprefIter = Y; // ... Y = f(YprefI

我对复制大型容器的最佳方式感兴趣。假设有一个向量容器,它存储例如60.000.000个条目(可能是长双倍)或更多的值。现在,如果要求解ODE(常微分方程),则有必要(根据使用的算法)复制用于计算的旧值,以更新新值。以下(想象的)例子:


如有任何评论,我们将不胜感激。Tobi

第一个片段基本上是这样的

for(i=0; i<iMax, ++i)
{
    vector<long double> YprefIter = Y;
    //  ...
    Y = f(YprefIter);
    //  ...
}

用于(i=0;ii如果需要制作副本,则需要制作副本。移动会使源向量为空,这样就不起作用。您应该尝试找到一种没有副本也能工作的算法。对两者进行基准测试,并选择最快的一种。一个像样的编译器可能能够为您的两个第一个示例生成相同的代码复制60000000个值的确切方法是:复制60000000个值。在某些地方,例如在视频游戏中,没有电源或蘑菇可以使复制X值的速度比其他方式快。移动语义避免在不需要复制值的情况下进行复制,而是根据C++11之前的语言规则进行复制。但是如果需要复制,move semantics无法让它在一团烟雾中消失。此外,如果可能的话,在向量中移动时复制该副本,而不是作为单独的过程。最小化缓存未命中可以将某些代码的速度提高一个数量级。像这样在连续内存块中移动非常有利于缓存。请记住这一点行军本身有一个不平凡的代价,你应该尽可能少地付出代价。@BlueTune如果
value\u type
是可复制的,那么任何好的向量实现都可以做到这一点。嗨@Bob\u,它会与我提到的上一个类似吗?我的意思是在交换指针的意义上(可能是交换在这里起作用。)@Tobi某种程度上更安全、更干净。参见和。
// This container is inside a class (so it is initialized and kept)
vector<long double> Y(60000000,0);

// Later on in a function
void solve()
{
    vector<long double> YprefIter (Y.size(), 0);

    for(i=0; i<iMax, ++i)
    {
        // Make a copy for the iteration algorithm
        // Better solution as we get rid of the memory allocation and deallocation 
        YprefIter = Y;
        ...
    }
}
// This container is inside a class (so it is initialized and kept)
vector<long double> Y(60000000,0);

// Later on in a function
void solve()
{
    // Create the second object
    vector<long double> YprefIter (Y.size(), 0);

    // Pointer 1 and Pointer 2
    vector<long double>* pToY = NULL;
    vector<long double>* pToYPref = NULL

    // Set pointer pToY to point to Y
    pToY = &Y;

    for(i=0; i<iMax, ++i)
    {
        // Switch the Pointer fields for each iteration
        if (i%2)
        {
            pToY = &Y;
            pToYPrefIter = &YPrefIter;
        }
        else
        {
            pToY = &YPrefIter;
            pToYPrefIter = &Y;
        }

        // Work with the pointers afterwards
        ...
    }
}
for(i=0; i<iMax, ++i)
{
    vector<long double> YprefIter = Y;
    //  ...
    Y = f(YprefIter);
    //  ...
}
// Initialize Y_old
vector<long double> Y_old = whatever(),
                    Y;
for(i=0; i<iMax, ++i)
{
    //  ...
    Y = f(Y_old);
    //  ...
    // The swap is implemented in terms of moves, it doesn't copy the values.
    std::swap(Y_old, Y);
}