1

重要なメソッドのパフォーマンスを最大化するために、別の質問では、配列を修正するのではなく、ネイティブに割り当てて使用することが提案されました。

私はC#で作業しており、安全でないコードやP/invokeの使用経験はありません。Googleで関連する例は見つかりませんでした。また、 VirtualAllocに関するMSDNの記事も役に立ちませんでした。

これは何十億回も呼ばれる方法であり、あらゆるビットのパフォーマンスが望まれます。

    public static readonly int[] HR = new int[32487834];
    public unsafe int eval(int c1, int c2, int c3, int c4, int c5, int c6, int c7)
    {
        fixed (int* HR = Evaluator.HR)
        {
            int p = HR[53 + c1];
            p = HR[p + c2];
            p = HR[p + c3];
            p = HR[p + c4];
            p = HR[p + c5];
            p = HR[p + c6];
            return (HR[p + c7]);
        }
    }

興味がある場合は、TwoPlusTwo-EvaluatorのC#ポートであり、 123mbのルックアップテーブルを使用して、比較のためにランダムな7枚のカードポーカーハンドのランクを返します。私のマシンでは、平均してランダムな順序で約8000万回の評価/秒、連続した順序で5億回の評価/秒(c1 = 0、c2 = 1、ループはすべての変数を52までインクリメント)します。

4

2 に答える 2

1

この例の主な問題は、ループコードの外部からfixedディレクティブを使用する必要があることです。このネストされた関数内で使用しても、実際には役に立たず、C#が内部でGCメモリ固定APIを呼び出すため、状況が悪化する可能性があります。したがって、はるかに優れたソリューションには、次のようなコードがあります。

public unsafe int eval(int* HR, int c1, int c2, int c3, int c4, int c5, int c6, int c7)
{
    int p = HR[53 + c1];
    p = HR[p + c2];
    p = HR[p + c3];
    p = HR[p + c4];
    p = HR[p + c5];
    p = HR[p + c6];
    return (HR[p + c7]);
}

fixed本質的には、 GCHandle.AddrOfPinnedObjectの言語構成の同義語です。あなたの場合、8つの配列フェッチの境界チェックを省略すると、その関数に入るたびにGCを介してメモリを固定および固定解除するコストを上回りましたが、おそらくそれほど多くはありません。

P / Invokeの使用は一般的に簡単ではありません。その領域に慣れるために数日を費やしたい場合を除いて、P/Invokeを使用しないことをお勧めします。C++を介したWin32/WinAPIプログラミングにまだ慣れていない場合は、さらに困難です。チェーンのできるだけ上位にメモリを固定できるように、コードを作り直すことをお勧めします。この特定の目的のために、オブジェクトコンストラクターの一部としてその配列のGCHandleを作成することもできます。

于 2012-12-31T23:54:52.690 に答える
0

C ++/Cliを使用してみてください。

ref class Evaluator
{
public:
  static Int32* HR;
  static Evaluator()
  {
    int size = 32487834;
    HR = (INT*)malloc(size * 4);
  }

  static Int32 Eval(Int32 c1, Int32 c2, Int32 c3, Int32 c4, Int32 c5, Int32 c6, Int32 c7)
  {
      Int32 p = HR[53 + c1];
      p = HR[p + c2];
      p = HR[p + c3];
      p = HR[p + c4];
      p = HR[p + c5];
      p = HR[p + c6];
      return (HR[p + c7]);

  }
};
于 2012-12-31T01:07:07.890 に答える