6

I'm trying to use System.Numerics.Vector<T> (documentation).

I wrote a simple unit test:

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

But it gave me a build error:

Member 'Vector.Count' cannot be accessed with an instance reference; qualify it with a type name instead

To my surprise, Vector<T>.Count is static.

So I tried:

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

Now the code builds but the unit test fails:

Assert.AreEqual failed. Expected:<3>. Actual:<2>.

What's going on?


Investigating I found:

Assert.AreEqual(2, Vector<double>.Count);
Assert.AreEqual(4, Vector<float>.Count);
Assert.AreEqual(4, Vector<int>.Count);
Assert.AreEqual(2, Vector<long>.Count);
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
  • @BoltClock thanks fixed. – Colonel Panic Feb 11 '16 at 15:44
  • Well, you are discovering why the class was not added to the framework. The value you get is also sadly wrong, on a Haswell or Broadwell processor it should be double the value since it will use the 256 bit YMM registers provided by AVX2. Leaves 2x perf on the table, hard to hide that implementation detail. AVX-512 is coming soon :) – Hans Passant Feb 11 '16 at 16:29
  • er... "wrong" is probably incorrect. Given https://en.wikipedia.org/wiki/Advanced_Vector_Extensions, OP's system is perhaps supporting only XMM's or SSE extension. – kchoi Nov 03 '16 at 00:44

2 Answers2

4

The documentation suggests that this is by design:

The count of a Vector instance is fixed, but its upper limit is CPU-register dependent.

Its purpose is to allow vectorizing operations using hardware capabilities, and thus its capacity is tied to your CPU's architecture.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
  • 4
    That statement from MSDN just makes things more confusing IMO, as the phrasing "The count of a Vector instance" implies that Count is in fact an instance member. – BoltClock Feb 11 '16 at 15:44
  • 1
    Thanks that wasn't obvious from the page I was reading "Returns the number of elements stored in the vector." https://msdn.microsoft.com/en-us/library/dn877911(v=vs.111).aspx – Colonel Panic Feb 11 '16 at 15:45
  • 1
    @ColonelPanic Yes, the documentation of this property is completely confusing. However, from my experience, it's quite often the case, that when MSDN documentation for a particular method/property is confusing, the "Remarks" section of the docs for the enclosing type contains valuable explanations. – BartoszKP Feb 11 '16 at 15:47
2

Vector may be somewhat confusing type. It is fixed predefined-length collection. It is fixed because its length is always == Vector<T>.Count. So if you do:

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

result is... :

<12, 13>

It is just drops all values over Vector<double>.Count which happens to be 2. The trick is that Vector<T>.Count may vary based on CPU architecture.

It is actually pretty low level primitive, as description says:

Represents a single vector of a specified numeric type that is suitable for low-level optimization of parallel algorithms.

Andrey
  • 59,039
  • 12
  • 119
  • 163