增加线程和进程优先级以减少处理器密集型并行应用程序的执行时间

Rah*_*han 5 .net c# optimization performance multithreading

我知道设置线程优先级是堆栈溢出的一个禁忌话题,但我确信我的应用程序是提高优先级的好候选人。为了证明这一点,我在下面解释了上下文。现在的问题是如何有效地做到这一点?

该应用程序是 .NET 4 (C#) 控制台应用程序,它执行复杂的算法,执行时间约为 5 小时。该算法根本不是内存密集型的,只是处理器密集型的。它执行数字运算,不执行任何磁盘 I/O、数据库连接、网络连接等。应用程序的输出只是一个最后写入控制台的数字。换句话说,该算法是完全自包含的,没有任何依赖关系。

该应用程序在其自己的专用 16 核 64 位机器上运行,该机器运行 Windows Server,其可用 RAM 远远超过其所需 (8GB)。专用我的意思是已购买服务器以独家运行此应用程序。

我已经通过广泛的分析、花哨的数学快捷方式和一些小技巧对代码进行了尽可能多的优化。

以下是伪代码的整体结构:

public static void Main ()
{
    Process.GetCurrentProcess().PriorityBoostEnabled = true;
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

    // Of course this only affects the main thread rather than child threads.
    Thread.CurrentThread.Priority = ThreadPriority.Highest;

    BigInteger seed = SomeExtremelyLargeNumber; // Millions of digits.

    // The following loop takes [seed] and processes some numbers.
    result1 = Parallel.For(/* With thread-static variables. */);

    while (true) // Main loop that cannot be parallelized.
    {
        // Processes result1.
        result2 = Parallel.For(/* With thread-static variables. */);

        // Processes result2.
        result1 = Parallel.For(/* With thread-static variables. */);

        if (result1 == criteria)
            break;

        // Note: This loop does not need to sleep or care about system responsiveness.
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,基于 SO 上与线程优先级相关的问题,我认为任何使用 ThreadPool 的东西都不应该在优先级方面被混淆。所以如果我需要切换到手动线程,就这样吧。

题:

  • 我应该如何将上面的代码更改为手动线程以从增加的线程优先级中受益(不使用线程池等)?
  • 在所有子线程上将优先级设置为最高甚至有帮助吗?我的意思是,子线程会只是相互争斗,还是会让它们比外部操作系统任务更具优势?
  • 考虑到有 16 个内核,我应该运行 16 个线程还是 15 个线程?对此是否有一般准则?
  • 将进程优先级设置为实时也有帮助吗?

Mar*_*mes 2

对于这样的应用程序,我希望更改优先级以使整体运行时间的差异为 0%。如果您的 CPU 使用率已经达到极限,所有 16 个核心都 100% 地执行实际工作,那么您就无能为力了。

  • 如果线程池的性能不如您的预期,我只会更改您的设计。如果任务管理器显示所有核心都为 100%,那就是这样。将进程优先级更改为实时也不会产生太大影响,但如果您可以足够提高进程/线程的优先级,您可能能够完全占用机器,直到您的应用程序完成,即。甚至阻止任务管理器获得任何 CPU。降低进程优先级也不会产生任何影响。尝试一下看看! (2认同)