Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to divide work between cores?

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 :

enter image description here

Edit :

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();

enter image description here

like image 691
Royi Namir Avatar asked Apr 14 '26 06:04

Royi Namir


2 Answers

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.

like image 181
Chris Sinclair Avatar answered Apr 16 '26 19:04

Chris Sinclair


@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.

like image 24
Joy George Kunjikkuru Avatar answered Apr 16 '26 18:04

Joy George Kunjikkuru



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!