C#并行处理选项

时间:2017-06-01 21:26:44

标签: c# multithreading parallel-processing threadpool

我试图让我的代码的一部分并行运行,我试图在c#中使用ThreadPool来避免任何麻烦,但是我似乎要求太多的池,我的代码实际运行速度较慢它!

下面的代码解释了我要做的事情,我有许多音频样本(取决于512-> 4096之间的缓冲区大小)需要插入,传播和读取节点(从n到任何地方)在延迟网络中= 4到n = 16)。这个HAS是在逐个样本的基础上发生的,所以我唯一的优化选择是采取插入/传播/读取的部分,并对网络中存在的每个节点进行并行操作。每个游戏框架调用一次该操作,并且在游戏的生命周期中需要该操作。查看分析器,散射操作需要花费大量时间,因此它是一个很好的候选者(我已经完成了传统优化)。目前,我让线程池工作人员为一个工作项中的所有节点完成工作,只是为了启动并运行,但工作可以稍后拆分。

我认为下面代码的问题是插入到线程池中的工作项的频率,我还读过一些线程需要一段时间才能启动的内容,所以如果线程池创建更多,则不会产生任何帮助。有没有人对其他并行处理方法有任何建议,或者可以发现我的线程池实现有任何错误?

public void propagateNetwork() {

    int numSampsToConsume = Mathf.min(inSamples.Count,buffersize);

    for (int i = 0; i < numSampsToConsume; i++) {
        outVal = 0.0f;
        inVal = inSamples.Dequeue () * networkInScale;

        directDelay.write (inVal);
        directVal = directDelay.read ();
        directVal *= directAtt;

        for (j = 0; j < network.Count; j++) {
            outVal += network [j].getOutgoing ();
            network [j].inputIncoming (inVal);
        }

        ThreadPool.QueueUserWorkItem (scatteringThreadPoolWrapper);
        scatteringThreadDone.WaitOne ();

        outVal += directVal;
        outSamples.Enqueue (outVal);
    }
}

public void scatteringThreadPoolWrapper(object threadConext) {
    doScatteringForNodeRange (0, network.Count);
}

public void doScatteringForNodeRange(int min,int max) {
    for (int i = min; i < max; i++) {
        network[i].doScattering (doLateReflections);
    }
    scatteringThreadDone.Set ();
}

1 个答案:

答案 0 :(得分:0)

也许使用Parallel.for会有效吗?我为每个循环迭代创建了一些局部变量,但我不知道所有操作都在做什么,以及如果并行运行可能会导致问题。

public void propagateNetwork() {
    int numSampsToConsume = Mathf.min(inSamples.Count,buffersize);

    Parallel.for(0, numSampsToConsume, i => {
        var outVal = 0.0f;
        var inVal = inSamples.Dequeue () * networkInScale;

        directDelay.write (inVal);
        var directVal = directDelay.read ();
        directVal *= directAtt;

        Parallel.for(0, network.Count, j => {
            outVal += network [j].getOutgoing ();
            network [j].inputIncoming (inVal);
        });

        doScatteringForNodeRange (0, network.Count);

        outVal += directVal;
        outSamples.Enqueue (outVal);
    });
}