Visual Studio 的 'watch' 错误地为 Vector<float> 中的一半数字显示零

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

这是 VS 2017 手表中的错误,还是我在做一些愚蠢的事情?它不显示 Vector 的一半内容。 (在我的系统上,Vector.Count 是 8)。

    [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
    }

这看起来很奇怪。为什么 inputVector 的 watch 没有显示一半的数字,即使它似乎在其他方面表现正确? Watch window 中也存在问题 - 但是,ToString() 正确显示 <1, 2, 3, 4, 5, 6, 7, 8>

我是 运行 Microsoft Visual Studio Professional 2017, 版本 15.4.2 15.7.5,并使用 System.Numerics.Vectors 的 v 4.5.0。我试过调试和发布;我关闭了 运行 优化(据我所知,在那种情况下你实际上并没有获得 SIMD 优化;但在这里,我只想调试一个算法)。

这可能是 JIT 优化的结果。 AFAIK,System.Numerics.Vector class 由 CPU 中的特殊指令支持(例如 AVX)。这意味着您初始化向量的数据可能只存在于寄存器中,根本不存在于堆栈中。

尝试在调试模式下编译您的代码,然后重试。

显然这实际上是一个已知问题 - "Debugger does not correctly handle bytes without a backing field." - https://github.com/dotnet/coreclr/issues/16280

您至少可以使用 string.Join,有趣的是,它始终 returns 格式为 <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);

而且您在调试器中总是只能看到 Vector<T> 实例容量的一半: