访问2D valarray的列切片

时间:2016-10-03 22:40:14

标签: c++ multidimensional-array valarray

请考虑以下代码段

#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线程没有提供答案。

1 个答案:

答案 0 :(得分:2)

首先,您没有2D valarray。您有valarray valarray个,这是您不应忽视的差异。

x = g[m][n];

只是看起来像数组式访问。它真的更接近

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

valarray的数据存储区是一个很好的连续内存块,但是如果你有一个M by N结构,那么你有M + 1 valarray可能分散在整个内存中。这可能会成为破坏性能的缓存未命中的噩梦。

您将不得不决定哪个更快,行切片或列切片更重要,因为只有一个将与内存流相关,而另一个需要针对粒度的缓存抖动副本。

目前

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

有效,因为它正在切割连续的内存块,

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

失败,因为它必须跨越M个不同的valarray来收集切片而std::slice无法做到这一点。您必须从构成列的每个valarray手动复制所需的元素。糟透了,是吗?

那你做什么?

你假装它! Muhuhahahahahahahaha!

不要valarray valarray。制作一个大的valarray大小的MxN。所以说再见

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而不是原始指针。