9 votes

Parallèle. Pour l'utilisation de l'étape != 1

Existe-t-il un moyen d'obtenir le Parallel.For version de ce for boucle ?

for (int i = 0; i < 100; i += 2) { DoStuff(i); }

Je ne vois pas de surcharge qui accepte un paramètre d'étape, mais je ne vois pas pourquoi cela serait logiquement impossible.

La réponse acceptée à ce y ce La question suggère d'utiliser Parallel.ForEach sur une série de int générés à l'aide de Enumerable.Range mais dans mon cas, j'utilise les données locales du fil. donc Parallel.ForEach n'est pas une option .

Une autre option consiste à vérifier si i % 2 == 0 dans le corps de ma boucle et return mais cela exécute toujours l'initialisateur de données locales du fil. Func et finaliseur Func . Vous trouverez ci-dessous un extrait de code illustrant cette option :

Parallel.For<Bar>(0, limit, 

    () => new Bar(), //thread local data initialize

    (i, state, local) => //loop body
    {
        if (i % 2 != 0) return local;
        local.foo += DoStuff(i);
        return local;
    },

    (local) => //thread local data post-action
    {
        lock (loopLocker)
        {
            globalData.foo += local.foo;
        );
    }
);

15voto

Ben Voigt Points 151460

Voici un indice :

for (int j = 0; j < 50; j++) { i = 2*j; DoStuff(); }

En général, voyez si vous pouvez déterminer le nombre d'itérations et une transformation du nombre d'itérations à la valeur de la variable.

7voto

Toan Nguyen Points 3342

Voici une autre façon de traiter les index échelonnés

private void ParallelForEachProcessSteppedIndexes()
        {
            Parallel.ForEach(SteppedIterator(0, 100, 2), (index) => DoStuff(index));
        }

private static IEnumerable<int> SteppedIterator(int startIndex, int endIndex, int stepSize)
        {
            for (int i = startIndex; i < endIndex; i = i + stepSize)
            {
                yield return i;
            }
        }

4voto

Tom Points 7654

La suggestion de Ben est très bonne pour les pas constants, par exemple +2, +3, etc.

Alternativement (si votre étape est aléatoire) vous pouvez utiliser Parallel.ForEach par exemple

int[] input = { 1, 3, 4, 5, 7, 10, 20, 25 }; 

Parallel.ForEach(input,
    () => new Bar(), //thread local data initialize
    (i, state, local) => //loop body
    {
        // your code
    },
    (local) => //thread local data post-action
    {
        // your code
    }

Variable i obtiendra des données de input réseau. Vous pourriez remplacer input con Enumerable.Range (ou le combiner avec With etc.)

Cela fonctionnerait parfaitement si vous vouliez n'obtenir qu'un nombre premier dans i variable.

0voto

anachostic Points 31

La réponse de Toan a fonctionné pour moi après avoir été convertie à la nouvelle fonction Iterator de VB.NET.

Private Sub LoopExample()
    Parallel.ForEach(SteppedIterator(1,100,5), AddressOf Test)

End Sub

Private Iterator Function SteppedIterator(startIndex As Integer, endIndex As Integer, stepSize As Integer) As IEnumerable(Of Integer)
    For i As Integer = startIndex To endIndex Step stepSize
        Yield i
    Next

End Function

Private Sub Test(i As Integer, state As ParallelLoopState, index As Long)
    Debug.WriteLine(i.ToString)
End Sub

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X