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

を使用しBigIntegerたことはありませんが、MSDN のドキュメントには、このメソッドを複数のスレッドに分散できると考えるに足る情報はありません。メソッドは、自分で再実装しない限り、複数のスレッドに分割することは不可能な単一の同期プロセスとして記述されているように見えます。

編集: 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;
}

そのプロセスと、前のループ ( exponentvalue、および を変更/更新する) へのビルドアップ/依存関係を見ると、この作業を分割して複数のスレッドに分散できる新しいルーチンを完全に作成することは、自明resultはありません。.

于 2013-04-28T12:47:42.097 に答える
1

これは素晴らしい質問であり、それが古いものであることを認識してください。

TPL (parallel.for/foreach) は、さまざまなコアのスレッドに作業を分散するために OS に依存していると思います。そのため、ボイラープレートの標準的なアプローチを明示的に訴えてこれを行うことはできません。TPLがそのために設計されたとは思いません。ただし、ProcessThread.ProcessorAffinity プロパティを使用して、スレッドが実行される特定のプロセッサに Task メソッドまたはデリゲート メソッドを割り当てることで、これを実現する方法がある場合があります。

于 2013-08-08T03:37:55.793 に答える
1

@royi、

TaskParallelLibrary とともにいくつかのロジックを保持すると、タスクを達成できます。デフォルトでは、.Net big integer は並列処理をサポートしていないと思います。以下を試してください

    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 に答える
-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 に答える