簡體   English   中英

c ++在3D矢量上最快的循環掃描

[英]c++ fastest loop scan over 3D vector

我想知道在3D矢量的每個元素上執行方法的最快方法是什么。

假設我們有:

std::vector<vector<vector<CLS>>> myVec;

我想以最快的方式執行以下循環:

 for(int cycle=0;cycle<10;cycle++) // do it 10 times
 {
    for(int i=0;i<myVec.size();i++)
    {
       for(int j=0;j<myVec[i][constant].size();j++)
       {
           foo(myVec[i][constant][j]);
       }

    } 
 }

值得一提的是,在我的案例中,中期指數總是不變的 是否足夠快地使用std :: vector或者你建議使用另一種類型的容器?

期待您的幫助。謝謝

以下會更快:

for(int i=0, int vecSize = myVec.size();i<vecSize;i++)
{
   for(int j=0, int currentLineSize = myVec[i][constant].size();j<currentLineSize;j++)
   {
       foo(myVec[i][constant][j]);
       //copy-paste this 10 times instead of having the outer loop
   }
} 

如果您對尺寸有所了解,可以執行更多展開。

迭代器的使用應該更快(在每次調用foo時都不必查看整個數組)。

typedef std::vector<CLS> v1;
typedef std::vector<v1> v2;
typedef std::vector<v2> v3;

for(int cycle=0;cycle<10;cycle++) // do it 10 times
{
    for(v3::const_iterator itOuter = myVec.begin(); itOuter != myVec.end(); ++itOuter)
    {
        const v1& vec = (*itOuter)[constant];
        for(v1::const_iterator itInner = vec.begin(); itInner != vec.end(); ++itInner)
            foo(*itInner);
    }
}

我沒有測量它(雖然甚至沒有嘗試編譯,所以原諒任何錯別字)

可能“盡可能快的方式”(以及最少的C ++ - 可能的方式,雖然它仍然是有效的C ++)將沿着這些方向:

const unsigned dim1 = 10; //first dimension
const unsigned dim2 = 20; //second
const unsigned dim3 = 30; //third
const unsigned nElem = dim1 * dim2 * dim3;

CLS myVec[nElem];

CLS *p = myVec, *q = myVec + nElem;

while (p < q)
{ foo(*p);
  ++p;
}

這消除了索引的所有計算,因為foo()似乎僅取決於所討論的CLS元素的值,而不取決於它在數組中的位置。 當然,以3D方式訪問myVec變得更加復雜( myVec[x * dim1 * dim2 + y * dim1 + z]等等 - 只是明確了C ++通常為你做的所有索引計算...)。

更改循環以“切片”數組以使一個維度保持不變將使其更復雜一些(實質上使其成為雙嵌套循環,在內循環終止處向指針添加額外的偏移量)。 有點像這樣(雖然我可能有相反的尺寸):

while (p < q)
{ CLS *r = p + dim3;
  while (p < r)
  { foo(*p);
    ++p;
  }
  p += dim2;
}

您可以創建一個遞歸函數對象:

class Foo {
public:
    template<typename Container>
    void operator()(Container& container) {
        for_each(container.begin(), container.end(), *this);
    }
    void operator()(CLS cls) {
        // do what you want
    }
};

Foo foo;
foo(myVec);

如果你想要效率,為什么要在3個循環中完成?

這是一個1

int cycle,
    i = 0,
    j = 0,
    counter;

for(cycle = 0, counter = 0; cycle < 10; counter++)
{
    j = counter % myVec[i][constant].size(); // It will go between 0 - myVec[i][constant].size()
    i += (!j) * !(!counter); // If j is reset (j =
    i %= myVec.size();
    foo(myVec[i][constant][j]); // Do your function
    cycle += (!i) * (!j) * !(!counter);
}

j = counter % myVec[i][constant].size()它將介於0myVec[i][constant].size()

i += (!j) * !(!counter)如果j被復位( j等於0 )所以使它為1如果counter0!(!0) = !1 = 0 )並且如果它是大於0所以5例如( !(!5) = !0 = 1 )因此i增加1

i %= myVec.size()它將介於0myVec.size()之間,並在到達myVec.size()時再次啟動( i = 0 myVec.size()

foo(myVec[i][constant][j])你的功能

cycle += (!i) * (!j) * !(!counter)如果i復位( i等於0 ),則將其設為1 ,對於j為相同如果counter大於0 ,則cycle增加1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM