最有效的方式处理与线程队列 [英] Most efficient way to process a queue with threads

查看:141
本文介绍了最有效的方式处理与线程队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个队列在其上挂起的傅立叶变换请求(相当耗时的操作)都放在 - 我们可以得到成千上万在某些情况下变换每秒的请求,因此它得是快

I have a queue onto which pending fourier transform requests (comparatively time consuming operations) are placed - we could get thousands of transform requests per second in some cases, so its gotta be quick.

我升级旧代码使用.NET 4中,以及移植到第三方物流。我想知道什么是最有效的(最快吞吐量)的方式来处理这个队列中的样子。我想使用所有可用的核心。

I'm upgrading the old code to use .net 4, as well as porting to TPL. I'm wondering what the most efficient (fastest throughput) way to handle this queue looks like. I'd like to use all cores available.

目前我正与一个BlockingCollection试验。我创建派生4个任务,阻断对BlockingCollection并等待传入​​的工作队列处理程序类。然后,他们处理该未决变换。代码:

Currently I am experimenting with a BlockingCollection. I create a queue handler class that spawns 4 tasks, which block on the BlockingCollection and wait for incoming work. They then process that pending transform. Code:

public class IncomingPacketQueue : IDisposable
    {
        BlockingCollection<IncomingPacket> _packetQ = new BlockingCollection<IncomingPacket>();

        public IncomingPacketQueue(int workerCount)
        {
            for (int i = 0; i < workerCount; i++)
            {
                Task.Factory.StartNew(Consume);
            }
        }

        public void EnqueueSweep(IncomingPacket incoming)
        {
            _packetQ.Add(incoming);
        }

        private void Consume()
        {
            foreach (var sweep in _packetQ.GetConsumingEnumerable())
            {
                //do stuff
                var worker = new IfftWorker();
                Trace.WriteLine("  Thread {0} picking up a pending ifft".With(Thread.CurrentThread.ManagedThreadId));
                worker.DoIfft(sweep);                

            }
        }

        public int QueueCount
        {
            get
            {
                return _packetQ.Count;
            }
        }

    #region IDisposable Members

    public void Dispose()
    {
        _packetQ.CompleteAdding();
    }

    #endregion
    }



请问这看起来像一个很好的解决方案?这似乎最大输出所有核心 - 虽然我不确定现在我应该有多少工人在我的产卵构造

Does this look like a good solution? It seems to max out all cores - although I'm currently unsure how many workers I should spawn in my constructor.

推荐答案

这看起来合理的。我发现 BlockingCollection 是相当快的。我用它来处理每秒请求数万。

That looks reasonable. I've found BlockingCollection to be quite fast. I use it to process tens of thousands of requests per second.

如果您的应用程序处理器的约束,那么你可能不希望创造更多的工人比你有核心。当然,你不想创造了很多更多的工人比内核。在一个四核的机器,如果你期望的大部分时间被花在了FFT的,然后四名工人会吃掉所有的CPU。更多的工人只是意味着更多的你有线程上下文切换来处理。该TPL通常将平衡,对于你,但没有理由创造,比方说,100名工人,当你不能处理超过屈指可数。

If your application is processor bound, then you probably don't want to create more workers than you have cores. Certainly you don't want to create a lot more workers than cores. On a quad core machine, if you expect most of the time to be spent doing the FFTs, then four workers will eat all the CPU. More workers just means more that you have thread context switches to deal with. The TPL will typically balance that for you, but there's no reason to create, say, 100 workers when you can't handle more than a handful.

我会建议你用3,4,5,6,7,和8工人运行测试。看看哪一个为您提供最佳的吞吐量。

I would suggest that you run tests with 3, 4, 5, 6, 7, and 8 workers. See which one gives you the best throughput.

这篇关于最有效的方式处理与线程队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆