通过将长时间运行的任务拆分为单独的进程来提高程序性能

Posted

技术标签:

【中文标题】通过将长时间运行的任务拆分为单独的进程来提高程序性能【英文标题】:Improve programs performance by splitting long running task into separate processes 【发布时间】:2018-06-08 06:46:06 【问题描述】:

我了解到,当您在单独的线程(并行)中运行长时间运行的操作时,当您的 PC 具有多个处理器内核时,性能会显着提高。在 C# 中有一个函数Parallel.ForEach,据我所知,它将长时间运行的操作拆分为单独的线程,这些线程在每个处理器内核上运行。虽然,如果只有一个核心,这个函数将作为一个简单的Foreach 循环(同步)运行。此外,如果您创建的线程数多于处理器内核数,甚至可能会产生负面影响。

我正在考虑创建一个单独的控制台应用程序,将 args 传递给它并在多个进程上运行它的 .exe,例如 start -WindowStyle Hidden SeparateProcess.exe

编辑: 我已经创建了一个这样的控制台应用程序

class Program

    static void Main(string[] args)
    
        for (int i = 0; i < 100; i++)
        
            Thread.Sleep(200);
            Console.WriteLine("" + i);
        
        Console.WriteLine();
        Console.WriteLine(Guid.NewGuid() + ": Process finalized.");
    

然后,使用powershell多次执行:

For ($i=0; $i -lt 10; $i++)
start -WindowStyle Normal SeparateProcess.exe 

这会在单核上运行时提高程序性能吗?

注意:长时间运行的任务是 Emgu CV 图像计算算法。

【问题讨论】:

多线程不仅仅用于利用多核。根据应用程序及其线程所做的事情,在单核机器上运行的多线程应用程序可能仍然比在单核机器上运行的单线程应用程序性能更高。多个进程的一大缺点是它们不能共享内存或资源,而具有多个线程的单个进程可以。 您的进程不受 CPU 限制——它大部分时间都在休眠。提高性能会是什么样子?它仍然会休眠 200 毫秒 100 次,并且需要大约相同的时间。写入都将花费相同的时间。 @RavB 在只有单核的机器上使用多线程有很多理由(毕竟,线程已经普遍使用了几十年,而多线程)核心计算机仅在短短十年内就很常见),但这些原因不是性能。在单核机器上,多线程代码的性能总是较低(因为您完成了相同的工作但有线程开销),但尽管有线程开销,但它仍然很有用。 【参考方案1】:

你应该通过尝试来检查自己,但是......

有没有办法在只有一个内核的情况下提高长时间运行的任务性能?

是的,但显然不是通过并行运行。您可以对代码使用性能分析器来找出哪些部分花费的时间最多,并尝试以更优化的方式重写它。

基于 cmets 编辑:

如果您尝试使用 CV 进行图像处理,并且您正在做的事情是 CPU 密集型(运行时使处理器最大化),那么并行化它不会对单个内核有所帮助(它们会竞争CPU)。

如果您正在做的事情必须等待 I/O 完成,那么并行化它将允许一些工作继续进行,而其他进程则等待 I/O。

这取决于你在做什么——你可能应该结束这个问题并问一个更具体的问题,详细说明你正在尝试做什么以及该任务的 CPU 密集程度。

(顺便说一句,如果可以的话,使图像处理速度更快的一种方法是预先调整图像的大小 - 您可能尝试对图像执行的许多操作在较小的版本上都可以正常工作 - 例如:面部检测) .

【讨论】:

问题是不是我写的代码需要很长时间才能完成,而是-EmguCV图像计算算法。 这需要时间(而且,它很可能会尽可能快地做到这一点——简历写得很好)。

以上是关于通过将长时间运行的任务拆分为单独的进程来提高程序性能的主要内容,如果未能解决你的问题,请参考以下文章

气流将长时间运行的任务标记为失败

具有长时间运行任务的单独线程中的计时器

如何使用气流检查长时间运行的 http 任务的状态?

分析非常长时间运行的任务

在 iOS 中实现长时间运行的后台任务

延迟长时间运行的计时器任务以提高滚动平滑度