【问题标题】:Reducing runtime of method from 24 hours to 1 hour [closed]将方法的运行时间从 24 小时减少到 1 小时 [关闭]
【发布时间】:2014-05-22 17:07:49
【问题描述】:

我有一个“For”循环,我需要从 0 运行到 2,147,483,647 (int.MaxValue)。在循环内部,我调用了一个方法来计算一个非常复杂的方程并返回每个参数的值。我希望得到最高的回报价值。

我的 for 循环的总运行时间大约需要 24 小时。如何以及如何将代码的运行时间减少到一小时?如果我使用分布式计算,可能需要 4 个小时?

    static void Main(string[] args)
    {
        CheckValuesZeroToMaxInt();
        Console.ReadLine();
    }

    private static void CheckValuesZeroToMaxInt()
    {
        for (int i = 0; i < int.MaxValue; i++)
        {
            ComplexMath(i);
        }
    }

我知道如何使用“Parallel.For”,但这仍然提供的帮助很少。如何获取我的 c# 代码并在计算机集群上运行它以立即从我的方法中获取返回值?是否有网站以低价或免费提供此服务?

【问题讨论】:

  • 那么您可以访问多少个内核?问题真的是令人尴尬的可并行化(看起来如此)吗?在具有多个内核的一台机器上执行此操作会更简单,但如果需要,您可以分发它。
  • 如果调用是相互独立的,为什么不直接使用Parallel.For()
  • 在不知道ComplexMath 在做什么的情况下,我不知道我们怎么可能给出完整的答案。一个空循环(没有函数调用)最多需要几秒钟。
  • ComplexMath跑得更快。这是一个翻转的答案,但请考虑以下问题:这里有一些代码需要 0.00001% 的执行时间。我还有一个功能需要 99.99999% 的时间,但我没有显示。如何让它快 24 倍?好吧,您可以在 30 多个核心计算机上运行它并对其进行并行化,或者在 30 台不同的计算机上运行它,每台计算机都执行该范围的一部分。或者,您可以优化需要花费所有时间的函数,并可能将其加速 100 或 1000 倍。
  • 正如@hatchet 所说,让ComplexMath 运行得更快,无论你是否利用并行性,因为无论你做什么,你获得的加速倍数都将适用。 This is the method I and many others use,寻找加速机会。如果您的ComplexMath 有任何提高速度的简单方法,它会找到它们。

标签: c# performance parallel-processing distributed-computing


【解决方案1】:

在一台机器上最简单的方法是使用Parallel.For-loop

private static void CheckValuesZeroToMaxInt()
{
    object maxValueLock = new object();
    int maxValue = int.MinValue;

    Parallel.For(0, int.MaxValue, i =>
    {
        int tmpMaxValue = ComplexMath(i);

        if (tmpMaxValue > maxValue)
        {
            lock(maxValueLock)
            {
                if (tmpMaxValue > maxValue)
                    maxValue = tmpMaxValue;
            }
        }
    }

    Console.WriteLine(maxValue);
}

但是,由于您的 ComplexMath 函数只需要大约 0.04 毫秒 ((24 / (2^31)) * 3600 * 1000) 即可执行,您可能会被持续锁定卡住,几乎不会得到任何改进。为了防止这种情况发生,我们可以改变上面的函数在一个线程中执行更多的步骤。

const long million = 1000*1000;

private static void CheckValuesZeroToMaxInt()
{
    object maxValueLock = new object();
    int maxValue = int.MinValue;

    Parallel.For(0, (int.MaxValue / million) + 1, i =>
    {
        int privateMaxValue = int.MinValue;

        for (long j = i * million; j < (i+1) * million && j < int.MaxValue; j++)
        {
            int tmpMaxValue = ComplexMath(j);

            if (tmpMaxValue > privateMaxValue)
            {
                privateMaxValue = tmpMaxValue;
            }
        }

        lock(maxValueLock)
        {
            if (privateMaxValue > maxValue)
                maxValue = privateMaxValue;
        }
    }

    Console.WriteLine(maxValue);
}

第二个版本应该随着处理器的数量线性扩展,所以如果你在一台有 24 核的机器上运行它,它将在 1 小时内完成。当然不是 Parallel。因为您可以使用任何类型的通信在多台机器之间分配计算。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    相关资源
    最近更新 更多