Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我能比这更快地将一维向量转换为二维向量吗?_C++_For Loop_Vector_2d Vector - Fatal编程技术网

C++ 我能比这更快地将一维向量转换为二维向量吗?

C++ 我能比这更快地将一维向量转换为二维向量吗?,c++,for-loop,vector,2d-vector,C++,For Loop,Vector,2d Vector,问题很简单。经过一些测试,以下是我发现的最有效的代码: //For the sake of the example, I initialize every entry as zero. vector<float> vector1D(1024 * 768, 0); vector<vector<float>> vector2D(768, vector<float>(1024,0)); int counter = 0; for (int i = 0;

问题很简单。经过一些测试,以下是我发现的最有效的代码:

//For the sake of the example, I initialize every entry as zero.
vector<float> vector1D(1024 * 768, 0); 
vector<vector<float>> vector2D(768, vector<float>(1024,0));

int counter = 0;
for (int i = 0; i < 768; i++) {
    for (int j = 0; j < 1024; j++) {
        vector2D[i][j] = vector1D[counter++];
    }
}
//为了示例,我将每个条目初始化为零。
向量向量1d(1024*768,0);
向量向量2D(768,向量(1024,0));
int计数器=0;
对于(int i=0;i<768;i++){
对于(int j=0;j<1024;j++){
vector2D[i][j]=vector1D[counter++];
}
}

有没有更快的方法?

使用
memcpy
可能会更快,因为这是复制内存的API的最低级别,并且可能存在编译器优化,可能会使用特定的指令等。如果更快:

for (int i = 0; i < 768; i++) {
    memcpy(vector2D[i].data(), &vector1D[i * 1024], sizeof(float) * 1024);
}
for(int i=0;i<768;i++){
memcpy(vector2D[i].data(),&vector1D[i*1024],sizeof(float)*1024);
}
请记住,您不应该将
memcpy
用于可复制的数据之外的任何内容。也就是说,它可以很好地用于
float
int
,但不适用于类,因为不会调用复制构造函数。

您可以重新映射访问元素的方式,而无需复制它们。您可以创建一个“视图”类来实现:

template<typename T>
class two_dee_view
{
public:
    two_dee_view(std::vector<T>& v, std::size_t row, std::size_t col)
        : v(v), stride(col) { if(v.size() < row * col) v.resize(row * col); }

    T& operator()(std::size_t row, std::size_t col)
        { return v[(row * stride) + col]; }

    T const& operator()(std::size_t row, std::size_t col) const
        { return v[(row * stride) + col]; }

    std::size_t col_size() const { return stride; }
    std::size_t row_size() const { return v.size() / stride; }

private:
    std::vector<T>& v;
    std::size_t stride;
};

int main()
{
    std::vector<double> v {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

    two_dee_view<double> v2d(v, 2, 3);

    for(auto row = 0U; row < v2d.row_size(); ++row)
        for(auto col = 0U; col < v2d.col_size(); ++col)
            std::cout << row << ", " << col << ": " << v2d(row, col) << '\n';
}

该类只维护对传递给构造函数的
std::vector
的引用。只要原始的
std::vector
存在但不再存在,您就应该只使用
two_dee\u视图。

如果出于某种原因必须使用向量向量,使用
memcpy
memmove
更快(因为这是一个步骤,如另一个答复中所述)。但是你应该使用STL,而不是自己做

vector<float> vector1D(1024 * 768, 0);
vector<vector<float>> vector2D(768, vector<float>(1024, 0));

for (int i = 0; i < 768; i++) {
  vector2D[i].assign(next(vector1D.cbegin(), 1024 * i),
                     next(vector1D.cbegin(), 1024 * (i + 1)));
}
vector1D(1024*768,0);
向量向量2d(768,向量(1024,0));
对于(int i=0;i<768;i++){
vector2D[i].assign(下一个(vector1D.cbegin(),1024*i),
接下来(vector1D.cbegin(),1024*(i+1));
}

这将产生一个直接的
memmove
(取决于STL实现),但更安全、优化和(可能)可读性更强。

一个非常有效的方法是创建一个视图,该视图提供2D向量的接口,同时仍然是1d向量。而不是
的内部循环(int j=0;j<1024;j++){
您可以尝试
std::copy
编译器可能能够在一个步骤中生成更高效地复制1024个元素的代码。但是您确定您真的想要一个
向量
?通常您想要处理存储在这样一个矩阵中的数据,然后将该数据连续地保存在内存中是目前大多数情况下的做法e efficent@M.A注意到。我将研究它,因为我以前从未听说过视图。如果您真的需要复制数据,我认为您现在的方式是最好的。如果您希望能够像访问2D数组一样方便地访问数据,您可以创建一个包装类来重载
运算符[]
并返回一个
std::span
(如果您使用的是c++17)或一个指针。
vector2D[i][j]
类似于
vector2D.ptr_to_data[i]。ptr_to_data[j]
,内存不一定是连续的。这可能导致缓存未命中,并且比
vector1D[j+i*1024]慢
。大多数对矩阵进行大量计算的库都会将这些矩阵连续存储在内存中。与
vector1D[j+i*1024]相比,这看起来更简单,比如
vector2D[i][j]
并不意味着它更高效。哇,我只是在调试模式下检查,但这样的计算时间从50毫秒下降到了2毫秒。那就可以了!@JohnKatsantas比较调试模式下的性能差异并没有什么帮助。有些东西在调试时可以更快,但在发布版本中要慢得多。在releas bu中测量性能ild与优化一个是很棘手的,因为你需要避免编译器将事情完全优化掉,因为你不需要对结果进行任何签名。@t.niese我已经编写了很多年了,但在大学里,我们实际上从来没有对代码进行过如此详细的优化。这是我第一次看到这样的细节。这更重要比我预想的还要糟糕。直到昨天我还不知道调试模式会降低我的代码速度。现在你告诉我在发布模式下有些东西会更慢。我现在很困惑:P@t.niese但是,即使在调试模式下,从50ms减少到2ms也是有意义的。我的意思是,既然我在调试模式下尝试了这两种方法,它应该是有意义的即使这两种方法的实际计时(50和2毫秒),也可以至少比较这两种方法可能不是真的。对吗?@JohnKatsantas不,调试需要50毫秒的东西在发布时可能只需要0.1毫秒,而调试需要2毫秒的东西在发布时可能需要1毫秒。根据在调试构建中进行的测量,您无法假设在启用优化的情况下,发布时什么性能更好。
vector<float> vector1D(1024 * 768, 0);
vector<vector<float>> vector2D(768, vector<float>(1024, 0));

for (int i = 0; i < 768; i++) {
  vector2D[i].assign(next(vector1D.cbegin(), 1024 * i),
                     next(vector1D.cbegin(), 1024 * (i + 1)));
}