1

我正在尝试使用一个基类 (SlotBase) 对老虎机行为进行并行编程建模,该基类将被代表每台机器的类覆盖。

在基类中,我有一个方法(尝试)调用后代类的方法(在基类中标记为抽象),该方法播放样本并通过使用输出参数返回结果,然后使用互斥锁更新基类的求和变量。

相关代码示例如下: 来自 SlotBase.cs:

#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));
        }
    }
}

.. 这实际上对SampleSizePeriodSize的小值非常有效,但随着值的增加,它很快就会挂起(或实际上挂起)。

我已经尝试注释掉变量更新并且挂起继续认真,这表明问题实际上与我实现Parallel.For循环的方式有关。

我几乎没有问题从头开始拆除它并重建以使其正常工作。我唯一真正重要的设计目标是我拥有相同的范例(一个基类,多个子类用于实现不同的插槽)。

我哪里错了?

4

0 回答 0