为什么 Vector<T>.Count 是静态的?

6

我正在尝试使用 System.Numerics.Vector<T> (文档)。

我编写了一个简单的单元测试:

var v = new System.Numerics.Vector<double>(new double[] { 12, 13, 14 });
Assert.AreEqual(3, v.Count);

但是编译时出现了错误:

成员“Vector.Count”无法使用实例引用访问;请改为使用类型名称

令我惊讶的是,Vector<T>.Count是静态的。

于是我尝试了:

var v = new System.Numerics.Vector<double>(new double[] { 12, 13, 14 });
Assert.AreEqual(3, Vector<double>.Count);

现在代码已经构建成功,但单元测试失败了:
Assert.AreEqual 失败。期望值为:<3>,实际值为:<2>。
发生了什么?

调查发现:

Assert.AreEqual(2, Vector<double>.Count);
Assert.AreEqual(4, Vector<float>.Count);
Assert.AreEqual(4, Vector<int>.Count);
Assert.AreEqual(2, Vector<long>.Count);

@BoltClock 谢谢,已经修复了。 - Colonel Panic
你正在发现为什么该类未被添加到框架中。你得到的值也很遗憾是错误的,在Haswell或Broadwell处理器上,它应该是该值的两倍,因为它将使用AVX2提供的256位YMM寄存器。这意味着性能可以提高两倍,很难隐藏这个实现细节。AVX-512即将推出 :) - Hans Passant
嗯... "错误"可能不准确。根据https://en.wikipedia.org/wiki/Advanced_Vector_Extensions的指示,OP的系统可能只支持XMM或SSE扩展。 - kchoi
2个回答

4

文档显示,这是设计上的要求:

Vector实例的数量是固定的,但其上限取决于CPU寄存器。

它的目的是允许使用硬件功能进行矢量化操作,因此其容量与您的CPU架构相关联。


4
在我看来,来自MSDN的那个语句只会让事情更加混乱,因为“一个Vector实例的计数”这样的措辞暗示了Count实际上是一个实例成员。 - BoltClock
1
谢谢,从我阅读的页面上并不明显,“返回存储在向量中的元素数量。” https://msdn.microsoft.com/en-us/library/dn877911(v=vs.111).aspx - Colonel Panic
1
@ColonelPanic 是的,这个属性的文档确实很令人困惑。然而,根据我的经验,当MSDN文档中某个方法/属性的说明不清晰时,封装类型的“备注”部分通常包含有价值的解释。 - BartoszKP

2

向量可能是一个有些令人困惑的类型。它是一个固定长度的预定义集合。它是固定的,因为它的长度始终等于Vector<T>.Count。所以如果你这样做:

var v = new Vector<double>(new double[] { 12, 13, 14 });
Console.WriteLine(v);

结果是...

:
<12, 13>

它只是删除了 Vector<double>.Count 以上的所有值,这个值恰好为2。诀窍在于,Vector<T>.Count 可能会根据CPU架构而变化。

实际上,它是非常低级的原语,如描述所说:

表示指定数值类型的单个向量,适用于并行算法的低级优化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接