0

我有一个非常奇怪的问题。这是我的代码:

<declare E,JV>

<perform some actions with E>
JV.Math_Mul(E);

////

public new void Math_Mul(Matrix a)
    {

        double[,] vC = new double[a.ColCount, this.RowCount];


        externExtensions.MatMul(vC,a.Values ,this.Values, a.RowCount, this.ColCount, a.ColCount);
        Values = vC;

        CopyB(B.Values,vC);
     }

    static unsafe void CopyB(double[,] B, double[,] val)
    {
        int Col = val.GetLength(1);
        int j = 0;
        fixed (double* pA = B, pB = val)
        {
            for (int i = 0; i < val.Length; i++)
            {
                if (i != j * Col)
                    pA[i-j] = pB[i];
                else
                    j++;

            }
        }
    }

在执行 CopyB 函数后,E 发生了一些事情(这很奇怪,因为它不是 CopyB 的参数)并且 VS 2012 告诉我:无法获取本地或参数“E”的值,因为它在该指令指针处不可用,可能是因为它已被优化掉。代码优化已关闭,此代码运行良好,直到我制作了 CopyB。那么,问题是什么?E会发生什么,我该怎么办?

PS CopyB 用于在乘法后更快地解析矩阵,这是我的数学工具的一部分,我使用块矩阵。

我将非常感谢任何帮助!

4

1 回答 1

5

让我们简化您的问题:

我正在调试器中查看此代码。

static void Foo(int a, int b)
{
  DoSomething(a);
  DoSomethingElse(b);
}

有时,在运行后尝试a在调试器中查看时,DoSomething我会收到消息“无法获取本地或参数 'a' 的值,因为它在此指令指针处不可用,可能是因为它已被优化掉。” 这是什么意思?

形式参数是一个变量,这意味着它必须作为存储位置来实现。由于形式参数的生命周期很短,因此可以在短期池上分配该存储位置。这意味着抖动将使其成为堆栈位置寄存器

假设它是一个寄存器。寄存器在 x86 领域是一种稀缺资源,因此抖动可能希望将该寄存器用于DoSomethingElse. 它知道它可以安全地这样做,因为它知道后面的任何内容都没有DoSomethingElse引用a; a现在就抖动而言“已死”,因此它的寄存器可用于其他用途。

调试器知道寄存器不再有意义,a所以它不会让你误以为寄存器的值是a. 该值消失了,因为它的存储现在被用于其他用途。

所以这就解释了为什么当我添加一个新的方法调用时调试器的行为发生了变化?

是的。在您的原始程序中,抖动不需要重新使用寄存器,因此它在整个方法调用中具有其原始值。

您的实际场景只是该场景的一个更复杂的版本,涉及三种方法。抖动可能会重新使用代表您的变量的寄存器E来做其他事情。

于 2013-03-04T16:28:49.717 回答