访问 2D valarrays 的列切片
Accessing column slices of 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;
}
在这里我可以访问行切片,但不能访问列切片(如注释中所示)。是否有任何解决方法来访问列切片?
这个 线程没有提供答案。
首先,您没有 2D valarray
。您有 valarray
个 valarray
,这是您不应忽视的差异。
x = g[m][n];
只是看起来像数组式访问。真的更接近
temp = g[m];
x = temp[n];
A valarray
的数据存储是一个很好的连续内存块,但如果您有一个 M×N 结构,则可能有 M+1 valarray
分散在整个内存中。这可能会导致性能下降的缓存未命中的噩梦。
您将不得不决定哪一个更重要是快速,行切片或列切片,因为只有一个会随着内存的流动而另一个需要一个缓存颠簸的副本。
目前
g[1][std::slice(0,10,1)];
之所以有效,是因为它正在分割一个连续的内存块,并且
g[std::slice(0,1,3)][0]
失败,因为它必须跨越 M 个不同的 valarray
s 才能收集切片,而 std::slice
不能这样做。您将必须从构成该列的每个 valarray
中手动复制所需的元素。糟透了,是吧?
那你是做什么的?
你假的!呜哈哈哈哈哈哈哈哈哈哈!
不要valarray
valarray
。制作一个 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
而不是原始指针。
考虑以下代码片段,
#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;
}
在这里我可以访问行切片,但不能访问列切片(如注释中所示)。是否有任何解决方法来访问列切片? 这个 线程没有提供答案。
首先,您没有 2D valarray
。您有 valarray
个 valarray
,这是您不应忽视的差异。
x = g[m][n];
只是看起来像数组式访问。真的更接近
temp = g[m];
x = temp[n];
A valarray
的数据存储是一个很好的连续内存块,但如果您有一个 M×N 结构,则可能有 M+1 valarray
分散在整个内存中。这可能会导致性能下降的缓存未命中的噩梦。
您将不得不决定哪一个更重要是快速,行切片或列切片,因为只有一个会随着内存的流动而另一个需要一个缓存颠簸的副本。
目前
g[1][std::slice(0,10,1)];
之所以有效,是因为它正在分割一个连续的内存块,并且
g[std::slice(0,1,3)][0]
失败,因为它必须跨越 M 个不同的 valarray
s 才能收集切片,而 std::slice
不能这样做。您将必须从构成该列的每个 valarray
中手动复制所需的元素。糟透了,是吧?
那你是做什么的?
你假的!呜哈哈哈哈哈哈哈哈哈哈!
不要valarray
valarray
。制作一个 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
而不是原始指针。