Reputation: 148524
I have this simple (dummy) code : (heavy computed : 30 sec in my machine)
BigInteger number = BigInteger.Pow(Int64.MaxValue, 300000);
Console.WriteLine(number);
Plinq will do the job division automatically . (divide work to threads). but it will work on Ienumerable (followed by AsParallel)
Here I don't have Ienumerable object. I just have 1 command.
How can I divide my command among the available cores ?
currently (as you can see) only 1 core is doing the hard work :
Putting it under Task will not divide it among all cores :
Task<BigInteger> t=Task.Factory.StartNew(()=>BigInteger.Pow(Int64.MaxValue, 300000));
Console.WriteLine(t.Result);
Console.ReadLine();
Upvotes: 3
Views: 2130
Reputation: 99
This is a great question and realize it is an old one.
I believe TPL (parallel.for/foreach) relies on the OS to distribute work to threads on various cores, so you would not be able to do this explicitly suing the boiler-plate, standard approaches. I do not think TPL was designed for that. But there may be a way to accomplish this by assigning a Task or delegate method to a particular processor that a thread should run on by using the ProcessThread.ProcessorAffinity property.
Upvotes: 1
Reputation: 1528
@royi,
If you keep some logic along with TaskParallelLibrary you can achieve the task. Bydefault I don't think .Net big integer supports parallelism. Try the below
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;
}
Now this works perfectly if your exponent is divisible by the procCount. You need to tweak the logic little to work with any exponent :-) If you face any difficult, let me know.
Upvotes: 1
Reputation: 23208
I haven't worked with BigInteger
, but I don't see anything in the MSDN documentation that would lend me to think that the method can be distributed to multiple threads. It appears as though the method is written as a single, synchronous process which would be impossible to break into multiple threads short of re-implementing it yourself.
EDIT: If you look at the Mono source code, or another open source implementation, you may be able to rewrite their Pow
methods to be muiti-threaded.
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;
}
Though looking at its process and its build-up/dependency on the previous loop (it alters/updates exponent
, value
, and result
) it may be difficult non-trivial to write a new routine altogether that can break this work up and distribute it to multiple threads.
Upvotes: 4
Reputation: 2010
That seem to work fine on Win 8 and .Net 4.0. The "arrow" Shows where I started Debugging. The load is not symetric, but all cores are being used.
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);
}
}
}
Upvotes: -2
Reputation: 31
if it is acceptable, you could delegate your work to a BackgroundWorker process, the framework will automatically dispatch the workload onto your 8 cores.
This object also permit you to start the process async (via the RunWorkerAsync)
It is very easy to use "multicore" threads through BW.
Upvotes: -1