3

我有这个简单的(虚拟)代码:(重计算:在我的机器上 30 秒)

BigInteger number = BigInteger.Pow(Int64.MaxValue, 300000);
Console.WriteLine(number);

Plinq 会自动进行工作划分。(将工作划分为线程)。但它可以在 Ienumerable 上工作(其次是 AsParallel)

这里我没有 Ienumerable 对象。我只有 1 个命令。

如何在可用核心之间划分我的命令?

目前(如您所见)只有 1 个核心在做艰苦的工作:

在此处输入图像描述

编辑 :

将其放在 Task 下不会将其划分为所有核心:

Task<BigInteger> t=Task.Factory.StartNew(()=>BigInteger.Pow(Int64.MaxValue, 300000));

Console.WriteLine(t.Result);
Console.ReadLine();

在此处输入图像描述

4

5 回答 5

4

我没有使用过,但我在MSDN 文档BigInteger中没有看到任何可以让我认为该方法可以分发到多个线程的内容。似乎该方法被编写为单个同步进程,除非您自己重新实现它,否则不可能分成多个线程。

编辑:如果您查看Mono 源代码或其他开源实现,您可能能够将他们的Pow方法重写为多线程。

public static BigInteger Pow (BigInteger value, int exponent)
{
    if (exponent < 0)
        throw new ArgumentOutOfRangeException("exponent", "exp must be >= 0");
    if (exponent == 0)
        return One;
    if (exponent == 1)
        return value;

    BigInteger result = One;
    while (exponent != 0) 
    {
        if ((exponent & 1) != 0)
            result = result * value;
        if (exponent == 1)
            break;

        value = value * value;
        exponent >>= 1;
    }

    return result;
}

尽管查看它的过程及其对前一个循环的建立/依赖关系(它改变/更新exponent、、value和),但是完全编写一个可以分解这项工作并将其分发到多个线程的新例程result可能很困难。 .

于 2013-04-28T12:47:42.097 回答
1

@royi,

如果您在 TaskParallelLibrary 中保留一些逻辑,则可以完成任务。默认情况下,我认为 .Net 大整数不支持并行性。试试下面

    pubilic BigInteger ParallelBigPow(Int64 value, int expo)
    {
        int procCount = Environment.ProcessorCount;
        BigInteger result = 1;
        Parallel.For(0, procCount, (index) => result = result * BigInteger.Pow(value, expo / procCount));
        return result;
    }

现在,如果您的指数可以被 procCount 整除,这将非常有效。您需要稍微调整逻辑以使用任何指数 :-) 如果您遇到任何困难,请告诉我。

于 2013-04-28T14:17:11.810 回答
1

这是一个很好的问题,并意识到这是一个古老的问题。

我相信 TPL (parallel.for/foreach) 依赖于操作系统将工作分配给各个内核上的线程,因此您将无法明确起诉样板标准方法。我不认为 TPL 是为此而设计的。但是可能有一种方法可以通过使用 ProcessThread.ProcessorAffinity 属性将任务或委托方法分配给线程应在其上运行的特定处理器来完成此操作。

于 2013-08-08T03:37:55.793 回答
-1

如果可以接受,您可以将您的工作委托给BackgroundWorker进程,该框架会自动将工作负载分派到您的 8 个内核上。

此对象还允许您启动进程异步(通过RunWorkerAsync

通过 BW 使用“多核”线程非常容易。

于 2013-04-28T12:25:49.097 回答
-2

这似乎在 Win 8 和 .Net 4.0 上运行良好。“箭头”显示我开始调试的位置。负载不是对称的,但所有内核都在使用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            BigInteger number = BigInteger.Pow(Int64.MaxValue, 300000);
            Console.WriteLine(number);
        }
    }
}

在此处输入图像描述

于 2013-04-28T13:01:45.230 回答