C# 高效多线程一个每秒返回值44100次的进程

C# 高效多线程一个每秒返回值44100次的进程,c#,multithreading,optimization,C#,Multithreading,Optimization,目前,我的代码如下所示: public float[] Next(int samples) { float[] result = new float[samples]; for (int i = 0; i < samples; ++i) result[i] = 0; foreach (var b in boards) { for (int i = 0; i <

目前,我的代码如下所示:

    public float[] Next(int samples)
    {
        float[] result = new float[samples];
        for (int i = 0; i < samples; ++i)
            result[i] = 0;
        foreach (var b in boards)
        {
            for (int i = 0; i < samples; ++i)
                result[i] += b.Next();
        }
        return result;
    }
但这只会让事情变得更糟

有没有一种方法可以在不产生巨大线程开销的情况下多线程执行此过程

通常只有不到10块板。永远不要超过100

board.Next()
方法与调用方法不同。也就是说,定义此
Next()
的类与
board
的类不同

已解决:

有点,我想

我替换了这个:

    Parallel.ForEach(boards, b =>
    {
        for (int i = 0; i < samples; ++i)
            result[i] += b.Next();
    });
Parallel.ForEach(单板,b=>
{
对于(int i=0;i
为此:

    Parallel.ForEach(boards, b =>
    {
        for (int i = 0; i < samples; ++i)
        {
            var next = b.Next();
            lock (result)
                result[i] += next;
        }
    });
Parallel.ForEach(单板,b=>
{
对于(int i=0;i

显然,C#在添加到时会自动锁定结果。这是我预料到的。我没想到的是,它在评估右手边之前就这样做了。因此,通过将加法和对Next()的调用拆分为单独的语句,允许并行调用Next()。

严重的是,您会犯更大的错误

对于循环来说,44100不是一个特别高的数字。但是你有一些初学者的错误:

浮动[]结果=新浮动[样本]

这是44100个分配,可能需要也可能不需要。这种类型if函数的标准是,控制函数传入一个数组,并表示它需要多少样本(可选,向上到数组的长度),您返回的不是数组,而是实际传递的样本数(因为可能会更少)

在考虑b.下一步的并行计算之前,我会测量它并把测量的数字放在这里,因为大多数时候这没有什么意义


这样可以避免分配—相信我,您不希望每秒分配44100个阵列。这简直是自杀。

b.Next()做什么?里面有足够的工作吗?你分析你的代码了吗?嗯,44100是一个标准的音频采样比特率。当然,您应该能够一次采样超过1位。或者你正试图使它比需要的速度快16或32倍。或者您应该一次读取更多的值,这样的板总是有一个缓冲区,使数据检索实用。与供应商/制造商讨论一下。每秒生成44100次多线程肯定是个坏主意,开销会抵消任何可能的收益。多线程会导致一些开销。如果对b.Next()的单个调用中没有足够的工作,那么开销将比b.Next()的多线程安全性增加更多的时间。b、 Next()应该足够大,可以从多线程中获益。方法的多线程版本不是线程安全的!添加时需要锁定变量
result
    Parallel.ForEach(boards, b =>
    {
        for (int i = 0; i < samples; ++i)
        {
            var next = b.Next();
            lock (result)
                result[i] += next;
        }
    });