Visual Studio's 'watch' incorrectly shows zero for half of the numbers in a Vector<float>
Asked Answered
O

3

4

Is this a bug in the VS 2017 watch, or am I doing something daft? It doesn't show half the contents of a Vector. (On my system, Vector.Count is 8).

enter image description here

    [Test]
    public void inspectVector()
    {
        var numbers = new float[] { 1, 2, 3, 4, 5, 6, 7, 8 };

        var inputVector = new Vector<float>(numbers);


        var five = inputVector[4]; //this is fine - 5

        float[] numbersCopiedBack = new float[8];  
        inputVector.CopyTo(numbersCopiedBack); //this is fine - 1, 2, 3, 4, 5, 6, 7, 8
    }

This seems odd. Why does the watch for inputVector not show half of the numbers, even though it seems to behave correctly otherwise? The problem is also there in the Watch window - however, ToString() correctly shows <1, 2, 3, 4, 5, 6, 7, 8>

I'm running Microsoft Visual Studio Professional 2017, Version 15.4.2 15.7.5, and using v 4.5.0 of System.Numerics.Vectors. I've tried in debug and release; I'm running with optimisations off (AFAIK you don't actually get the SIMD optimisations in that case; but here, I just want to debug an algorithm).

Organzine answered 28/7, 2018 at 11:8 Comment(1)
Is Vector<float> the vector defined in System.Numerics?Theodosia
O
2

Apparently this is in fact a known issue - "Debugger does not correctly handle bytes without a backing field." - https://github.com/dotnet/coreclr/issues/16280.

Organzine answered 31/7, 2018 at 9:34 Comment(1)
There is also github.com/dotnet/runtime/issues/9688 Debugger does not correctly handle bytes without a backing fieldBelen
V
1

This is probably an effect of JIT optimization. AFAIK, the System.Numerics.Vector class is backed by special instructions in the CPU (e.g. AVX). This means that the data you initialized the vector with may exist only in registers and not on the stack at all.

Try to compile your code in Debug mode and try again.

Venose answered 28/7, 2018 at 11:58 Comment(3)
I'm running with optimisations off - which AFAIK should mean that you don't get the SIMD instructions coming into play. I know getting those instructions going is the point of vector, but here I'm just trying to test drive/debug an algorithm.Quamash
@topomorto: if Vector is using 128-bit vectors, but your debugger is looking at the full 256-bit width of the AVX vector for some reason, that would explain it. I don't use C#, but vmovups xmm, [mem] zero-extends into the full vector register (ymm or zmm if your CPU supports AVX or AVX512.Sharper
I am not sure if turning off compile time optimization will remove SIMD instructions. SIMD is a property of the JIT rather than the compiler. In the early days of the 64-bit JIT there was an environment variable to control this at run time, gist.github.com/richlander/d29dc4fe4e8032de5c92Venose
B
0

You can at least use string.Join, which interestingly always returns with the format <n1, n2, n3, ...>

Vector<int> powersOfTwo = new Vector<int>(Enumerable.Range(0, Vector<int>.Count).Select(i => 1 << i).ToArray());
string powersOfTwoString = string.Join("abc", powersOfTwo);

enter image description here

And you will always only see half the capacity of the Vector<T> instance in the Debugger:

enter image description here

enter image description here

Belen answered 20/12, 2021 at 0:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.