Schleifenparallelisierung



  • Hallo.

    Ich möchte in C# eine Schleife parallelisieren. In MSDN habe ich dazu folgendes gefunden:

    Parallel.For(0, N, i =>
                {
                    int vF = i * N;
    
                    for(int j=0;j< N; j++)
                    {
                        out[N * j] = in[j + vF];
                    }
                });
    

    Mein Problem ist jedoch, dass out eine Referenz ist und da spielt C# nicht mit.
    Fehlermeldung:
    Severity Code Description Project File Line
    Error CS1628 Cannot use ref or out parameter 'output' inside an anonymous method, lambda expression, or query expression

    Gibt es eine andere, einfache Möglichkeit in C# Schleifen zu parallelisieren oder das Problem zu umgehen?

    Meine komplette Funktion:

    static void TippIt<T>(T[] in, int N, ref T[] out)
            {
                #region Local variables
                int N2 = input.Length / N;
                #endregion
    
                #region Transposing matrix vector
                Parallel.For(0, N2, i =>
                {
                    int vF = i * N;
    
                    for (int j = 0; j < N; j++)
                    {
                        output[N* j] = input[j + vF]; /*Fehlermeldung*/
                    }
                });
                #endregion
            }
    


  • Hi,

    warum übergibst du das Array überhaupt als ref Parameter, wenn du nur die Werte darin änderst?

    Viele Grüße
    KaPtainCugel



  • Hi.

    Die Funktion ist mir so vorgegeben worden. Ich soll lediglich den Rumpf dafür programmieren.

    Ja, ich gebe es zu - das ist meine "Hausaufgabe" aber ich möchte ja nur Hilfe und nicht, dass ihr das für mich macht.

    Kann ich die Referenz vielleicht als private Variable (wie man priv. Variablen in einer Parallel.For Schleife erzeugt weiß ich) übergeben oder wo liegt hier das Problem?



  • CJens schrieb:

    Kann ich die Referenz vielleicht als private Variable (wie man priv. Variablen in einer Parallel.For Schleife erzeugt weiß ich) übergeben oder wo liegt hier das Problem?

    Ich vermute dass du das richtige meinst. Wenn du es in Code zeigst könnten wir es dir sicher sagen.

    Zum Thema warum das so wie du es versucht hast nicht erlaubt ist...

    Also es geht nicht, weil es nur mit viel Overhead umsetzbar wäre. Und vor allem Overhead der überall zu bezahlen wäre wo man Zeugs per ref bzw. out übergibt, egal ob das dann an Lambdas weitergereicht wird oder nicht.

    Grund ist dass bei nem ref bzw. out Parameter quasi die Adresse einer Variable der aufrufenden Funktion übergeben wird. (Bzw. auch evtl. die Adresse einer Membervariable eines Objekts, aber das wäre die weniger problematische Variante.)

    Lokale Variablen leben typischerweise auf dem Stack, und werden damit ungültig sobald die Funktion der sie gehören verlassen wird. Das Lambda kann aber ne beliebig lange Lebenszeit haben. Daher darf man dem Lambda die Adresse einer lokalen Variable nicht geben. Daher kein ref/out bei Lambdas.

    Du kannst aber natürlich den aktuellen Wert eines ref/out Parameters in eine andere, eigene lokale Variable kopieren und diese dann im Lambda einfangen.


Log in to reply