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実行後にデバッガーで確認しようとすると、 「ローカルまたは引数'a'の値を取得できません。この命令ポインターでは使用できないため、最適化されている可能性があります。」DoSomethingというメッセージが表示されることがあります。これは何を意味するのでしょうか?

仮パラメータは変数であり、保存場所として実装する必要があることを意味します。正式なパラメータは有効期間が短いため、その保存場所を短期プールに割り当てることができます。そして、それはジッターがそれをスタック位置またはレジスタにすることを意味します。

レジスターだとしましょう。レジスターはx86ランドでは希少なリソースであるため、ジッターはそのレジスターをで他の何かに使用したい場合がありますDoSomethingElseDoSomethingElse後は何も参照しないことを知っているので、安全にそれを行うことができることを知っていaます。aジッタに関する限り、は「デッド」になっているため、そのレジスタを他の目的に使用できます。

デバッガーは、レジスターがもはや意味を持たないことを認識しているaため、レジスターの値がの値であると誤解されることはありませんa。そのストレージが現在他の目的で使用されているため、その値はなくなりました。

これは、新しいメソッド呼び出しを追加したときにデバッガーの動作が変更された理由を説明していますか?

はい。元のプログラムでは、ジッターはレジスターを再利用する必要がなかったため、メソッド呼び出し全体で元の値を持っていました。

実際のシナリオは、このシナリオのより複雑なバージョンであり、3つの方法が関係しています。Eジッタは、変数を表すレジスタを他の何かに再利用している可能性があります。

于 2013-03-04T16:28:49.717 に答える