如何在并行后跟踪循环值



我有一个用于循环的嵌套,它需要30秒才能运行,我希望根据我的机器上的内核数并并行化。

原始循环:

var currentCap = model.LoanCap;
var currentRlRate = model.RlRate;
var maxRateObj = new Dictionary<string, double>();
var maxRateOuterLoopCount = 0;
var maxRateInnerLoopCount = 0;
for (var i = currentRlRate + rlRateStep; i <= maxRlRate; i += rlRateStep)
{
    maxRateOuterLoopCount++;
    var tempFyy = currentFyy;
    var tempIrr = currentIrr;
    var lowestCapSoFar = currentCap;
    var startingCap = maxRateObj.ContainsKey(capKey) ? maxRateObj[capKey] : currentCap;
    for (var j = startingCap - capStep; j >= minCap; j -= capStep)
    {
        maxRateInnerLoopCount++;
        tempModel = new ApplicationModel(model);
        var tempIrrAndFyy = GetIrrAndFyyTuple(tempModel, i, j, precision);
        var updatedIrr = tempIrrAndFyy.Item1;
        var updatedFyy = tempIrrAndFyy.Item2;
        // stop decrementing cap because we got a good-enough IRR to save this pair
        if (Math.Abs(currentIrr - updatedIrr) >= irrDiffPrecision || updatedFyy < minFyy)
        {
            var endingCap = j + capStep; // go back one step since we just stepped out of bounds
            maxRateObj = new Dictionary<string, double>
            {
                {rlRateKey, i },
                {capKey, endingCap }
            };
            // set vars so the outer loop can check if we are still operating within constraints
            lowestCapSoFar = endingCap;
            tempIrr = updatedIrr;
            tempFyy = updatedFyy;
            break;
        }
    }
    // Break out of the outerloop if the cap gets too low
    if (lowestCapSoFar <= minCap) { break; }
    // ... or if Fyy gets too low (when credit policy is enforced)
    if (enforceFyyPolicy && tempFyy < minFyy) { break; }
    // ... or if Irr gets too low (when credit policy is enforced)
    if (enforceIrrPolicy && Math.Abs(tempIrr - targetIrr) > irrDiffPrecision) { break; }
}

现在,当我将此循环移动到Parallel.For()的主体中时,我将失去以前对可变i的上下文...我如何获得该功能,因为我需要maxRateObj

var degreeOfParallelism = Environment.ProcessorCount;
var result = Parallel.For(0, degreeOfParallelism, x =>
{
    var tempFyy = currentFyy;
    var tempIrr = currentIrr;
    var lowestCapSoFar = currentCap;
    var startingCap = maxRateObj.ContainsKey(capKey) ? maxRateObj[capKey] : currentCap;
    for (var j = startingCap - capStep; j >= minCap; j -= capStep)
    {
        tempModel = new ApplicationModel(model);
        var tempIrrAndFyy = GetIrrAndFyyTuple(tempModel, i, j, precision);  // i IS NOT DEFINED HERE!
        var updatedIrr = tempIrrAndFyy.Item1;
        var updatedFyy = tempIrrAndFyy.Item2;
        // stop decrementing cap because we got a good-enough IRR to save this pair
        if (Math.Abs(currentIrr - updatedIrr) >= irrDiffPrecision || updatedFyy < minFyy)
        {
            var endingCap = j + capStep; // go back one step since we just stepped out of bounds
            maxRateObj = new Dictionary<string, double>
            {
                {rlRateKey, i }, // i IS NOT DEFINED HERE!
                {capKey, endingCap }
            };
            // set vars so the outer loop can check if we are still operating within constraints
            lowestCapSoFar = endingCap;
            tempIrr = updatedIrr;
            tempFyy = updatedFyy;
            break;
        }
    }
    // Break out of the outerloop if the cap gets too low
    if (lowestCapSoFar <= minCap) { return; }
    // ... or if Fyy gets too low (when credit policy is enforced)
    if (enforceFyyPolicy && tempFyy < minFyy) { return; }
    // ... or if Irr gets too low (when credit policy is enforced)
    if (enforceIrrPolicy && Math.Abs(tempIrr - targetIrr) > irrDiffPrecision) { return; }
});

不做degreeOfParallelism并行迭代次数。在您的并行循环中执行与以前相同数量的迭代,但使用ParallelOptions.MaxDegreeOfParallelism

在我看来,这是执行从0到numSteps的平行循环(以下计算(,设置环路的MaxDegreeOfParallelism,然后从循环体中x的值重新建立i。类似...

var start = (currentRlRate + rlRateStep);
var end = maxRlRate;
var numSteps = (end - start) / rlRateStep;
Parallel.For(0, 
    numSteps, 
    new ParallelOptions { 
        MaxDegreeOfParallelism = degreeOfParallelism 
    }, 
    x => {
        var i = (x * rlRateStep) + start;
        //lean on i
    });

相关内容

  • 没有找到相关文章

最新更新