2016-10-03 64 views
1

考慮下面的代碼片段,訪問2D的列切片valarrays

#include <iostream> 
#include <valarray> 

using namespace std; 

std::ostream & operator<<(std::ostream & out, const std::valarray<int> inputVector); 
typedef std::valarray<std::valarray<int> > val2d; 

int main() 
{ 
    val2d g(std::valarray<int>(10),4); 

    for (uint32_t n=0; n<4; ++n){ 
     for (uint32_t m=0; m<10; ++m){ 
      g[n][m] = n*10 + m; 
     } 
    } 
    std::valarray<int> g_slice_rs = g[1][std::slice(0,10,1)]; // row slice 
    //std::valarray<int> g_slice_cs = g[std::slice(0,1,3)][0]; // column slice (comment out) 

    cout<<"row slice :: "<<g_slice_rs<<endl; 
    //cout<<"column slice :: "<<g_slice_cs<<endl; // (comment out) 
    return 0; 
} 

std::ostream & operator<<(std::ostream & out, const std::valarray<int> inputVector) 
{ 
    uint32_t vecLength = inputVector.size(); 
    out<<"["; 
    for (uint32_t i=0; i<vecLength; ++i) 
    { 
    out <<inputVector[i]<<", "; 
    } 
    out<<"]"<<endl; 
    return out; 
} 

在這裏我能夠訪問該行片,但不是列切片(如在評論中所示)。是否有任何解決方法來訪問列切片? This線程不提供答案。

回答

2

首先,您沒有2D valarray。您有valarrayvalarray s,這是您不應忽視的差異。

x = g[m][n]; 

只看起來像一個數組式訪問。這真的接近

temp = g[m]; 
x = temp[n]; 

一個valarray的數據存儲是內存的一個很好的連續塊,但如果你有N個結構中的男,你有M + 1 valarray小號可能分散在整個內存。這可能會變成性能扼殺緩存未命中的噩夢。

你將不得不決定哪一個更重要,快速,行切片或列切片,因爲只有一個將與內存流一起進行,另一個需要對穀物進行緩存顛簸拷貝。

目前

g[1][std::slice(0,10,1)]; 

的作品,因爲它是切片一個連續的內存塊,並

g[std::slice(0,1,3)][0] 

失敗,因爲它必須在M個不同valarray拿不到的地方收集切片和std::slice不能去做。您將不得不手動複製構成列的每個valarray所需的元素。吮吸,是吧?

那麼你會怎麼做?

你假的! Muhuhahahahahahahaha!

請勿使valarrayvalarray s。製作一個尺寸爲MxN的大valarray。所以說再見

std::valarray<std::valarray<int> > g(std::valarray<int>(10),4); 

,並招呼

std::valarray<int>(10*4); 

現在你可以利用std::slice的步幅參數抓住每十元

std::slice(column_to_slice,4,10); 

而作爲一個額外的獎勵你現在有一塊連續的內存塊,所以至少應該緩解一些緩存磨損的問題。如果步幅太大,你仍然發暈。

我全心全意地推薦將它包裝在一個對象中,以使訪問和管理更容易。 Something like this,除了使用valarray而不是原始指針。

+0

我試圖避免把它變成一維數組,但我想沒有辦法繞過它。 – Naveen