1

個々のマシンを表すクラスによってオーバーライドされる基本クラス (SlotBase) を使用して、並列プログラミングでスロット マシンの動作をモデル化しようとしています。

基本クラスには、サンプルを再生し、出力パラメーターを使用して結果を返し、相互に排他的なロックを使用して、基本クラスの合計変数。

関連するコード サンプルは次のとおりです

#region Member Variables
protected long m_CoinIn;
protected long[] m_CoinOut;
protected string[] m_FeatureList;
protected long[] m_HitCount;
// .. and many more, but redacted for length
#endregion


protected abstract void PlaySample(long sampleSize, out long coinIn, out long[] coinOut, out long[] hitCount);

protected override void DoSimulation() {
    // No need to intialize these, as the calling routine will, and only it knows how big the arrays need to be, and so forth.
    object mutex = new object();

    if (ParallelMode) {
        int periodCount = (int)(BatchSize / PeriodSize);
        Parallel.For(0, periodCount, delegate(int i) {
            long coinIn;
            long[] coinOut;
            long[] hitCount;

            PlaySample(PeriodSize, out coinIn, out coinOut, out hitCount);
            lock (mutex) {
                Console.WriteLine("Coin in this batch: {0}", coinIn);
                m_CoinIn += coinIn;

                for (int j = 0; j < m_FeatureList.Length; ++j) {
                    m_CoinOut[j] += coinOut[j];
                    m_HitCount[j] += hitCount[j];
                }
            }
        });
    }
}

.. そして典型的なサブクラスの実装から:

protected override void PlaySample(long sampleSize, out long coinIn, out long[] coinOut, out long[] hitCount) {
    switch (WagerIndex) {
        case (int)WagerType.Main: {
            RNG localRNG = SpawnRNG();
            coinIn = 0;
            coinOut = new long[m_FeatureList.Length];
            hitCount = new long[m_FeatureList.Length];


            for (long iter = 0; iter < sampleSize; ++iter) {
                coinIn += m_LinesPlayed;
                double[] output = GetSpinResults(ref localRNG, (int)SpinMode.MainSpin);

                for (int i = 0; i < m_FeatureList.Length; ++i) {
                    coinOut[i] += (long)output[i];
                    if (output[i] > 0) ++hitCount[i];
                }
            }                   
            break;
        }
        default: {
            throw new Exception(string.Format("Wager Type index {0} not supported", WagerIndex));
        }
    }
}

.. これは実際には、 SampleSizeとPeriodSizeの値が小さい場合に非常に効果的に機能しますが、値が大きくなるとすぐにハング (または実質的にハング) します。

変数の更新をコメントアウトしようとしましたが、ハングが本格的に続いています。これは、問題が実際にParallel.Forループを実装している方法にあることを示唆しています。

これをゼロから解体し、再構築してこれを機能させることに問題はありません。私の唯一の本当に重要な設計目標は、同じパラダイム (1 つの基本クラス、異なるスロットの実装のための複数のサブクラス) を持つことです。

どこが間違っていますか?

4

0 に答える 0