并行化非常大的阵列基本转换

时间:2014-03-24 22:12:27

标签: c# multithreading math set-theory

我有一种将转换为 newBase 长度长度的方法。

英语的逻辑是:

If we calculated every possible combination of numbers from 0 to (c-1)
with a length of x
what set would occur at point i

虽然下面的方法确实很有效,但由于使用了非常大的数字,可能需要很长时间才能完成:

例如,value =(((65536 ^ 480000)-1)/ 2),newbase =(65536),length =(480000)在64位架构(四核PC)上需要大约一个小时才能完成。

private int[] GetValues(BigInteger value, int newBase, int length)
{
    Stack<int> result = new Stack<int>();

    while (value > 0)
    {
        result.Push((int)(value % newBase));

        if (value < newBase)
            value = 0;
        else
            value = value / newBase;
    }

    for (var i = result.Count; i < length; i++)
    {
        result.Push(0);
    }

    return result.ToArray();
}

我的问题是,如何将此方法更改为允许多个线程计算出部分数字的内容?

我正在使用C#,但如果你不熟悉它,那么伪代码也可以。

注意:该方法来自此问题:Cartesian product subset returning set of mostly 0

1 个答案:

答案 0 :(得分:2)

如果GetValues方法确实是瓶颈,那么可以采取一些措施加快速度。

首先,每次循环时你都要除以newBase。由于newBaseint,并且BigInteger除法方法除以BigInteger,因此您可能需要花费int - 至{{每次迭代都会转换{1}}。你可能会考虑:

BigInteger

此外,您可以通过拨打DivRem

将分数减半
BigInteger bigNewBase = newBase;

正如评论中提到的那样,另一个优化是将数字存储在预先分配的数组中。您必须致电Array.Reverse以正确的顺序获取它们,但这几乎没有时间。

顺便说一下,这种方法不适合并行化,因为计算每个数字取决于前一个数字的计算。