7 Stimmen

Wie schreibt man in ein Array aus einer dispatch_apply (GCD) Schleife?

Ich habe einen Code geschrieben, um die Dynamik eines großen Satzes gekoppelter Hauptgleichungen mit Hilfe der Runge-Kutta-Methode zu berechnen. Der Code enthält eine Menge for-Schleifen, wobei jeder Schritt unabhängig ist. Ich beabsichtige, Grand Central Dispatch zu verwenden, um das Programm zu beschleunigen. Ich habe meinen Versuch auf ein Beispiel gestützt, das ich unter http://www.macresearch.org/cocoa-scientists-xxxi-all-aboard-grand-central . Weder mein Code noch das Beispiel auf macresearch kompilieren auf meinem Rechner (MacOSX 10.6.8 Xcode 4.0.2). Also hier ist mein Code:

...
    double values[SpaceSize], k1[SpaceSize];    

        for ( int t=1 ; t<Time ; t++ ) {

            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

            //k1
            for (int k=0 ; k<SpaceSize ; k++ ) values[k]=Concentration[k][t-1];

            dispatch_apply(SpaceSize, queue,
                       ^(size_t k)  {
                           k1[k]=h * derives(values, SpaceSize, k); //<--error      
                                    }
                        );
...

Es bricht mit dem Fehler:

Semantisches Problem: Kann sich nicht auf eine Deklaration mit einem variabel modifizierten Typ innerhalb eines Blocks

Ich habe versucht, die Arrays (Werte, k1) durch Vektoren zu ersetzen, aber dann erhalte ich stattdessen eine andere Fehlermeldung:

Semantisches Problem: Nur-Lese-Variable ist nicht zuweisbar

Das ist der Punkt, an dem ich nicht weiterkomme, da ich nicht wirklich weiß, was mir diese Fehlermeldungen sagen wollen. Ich habe schon einige Zeit mit der Suche verbracht und mich umgehört, ob mir jemand helfen kann. Ich wäre sehr dankbar für Tipps oder bessere Lösungsansätze.

16voto

Kazuki Sakamoto Punkte 13924

Fehler: kann nicht auf eine Deklaration mit einem Array-Typ innerhalb eines Blocks verweisen

Bei der Implementierung von Blöcken ist es nicht erlaubt, von Blöcken aus auf ein C-Array zuzugreifen. (Ich kann die Dokumentation dazu nicht finden...)

Es gibt eine einfache Lösung :-)

double valuesArray[SpaceSize], k1Array[SpaceSize];    
double *values = valuesArray, *k1 = k1Array;

0 Stimmen

Herzlichen Dank! Das scheint das Problem zu beheben!

2voto

Jeremy W. Sherman Punkte 35413

Um in einer erfassten Variablen zu speichern, müssen Sie die __block Speicher-Spezifizierer zu seiner Deklaration hinzufügen. Das sollte die std::vector Problem, das Sie sehen.

Das Problem mit einem variabel modifizierten Typ lässt es so klingen, als würden Sie ein Array mit variabler Länge verwenden. Auf diese kann innerhalb von Blöcken nicht verwiesen werden, da sie nicht zuverlässig in den Kontext des Blocks kopiert werden können (im Grunde eine eigene C struct Typ), und sie können die offsetof -Berechnungen bei der Arbeit mit dem Kontext. Sie können dieses Problem lösen, indem Sie mit einer Variablen fester Größe arbeiten (verwenden Sie einfach die maximale Größe, die Sie benötigen), die Arrays in den globalen/statischen Speicher verschieben oder einen Zeiger zuweisen und die Zeigerarithmetik durchführen, um selbst auf die zweite Dimension zuzugreifen.

0 Stimmen

Wie füge ich den __block specifier hinzu. In der Xcode-Dokumentation gibt es ein Beispiel dafür in Verbindung mit dispatch_apply, aber das funktioniert nicht. (Ich habe sogar ein Ticket von jemandem gefunden, der sich darüber beschwert) Ich ändere die Größe der Arrays nicht, deshalb habe ich die Fehlermeldung nicht verstanden. Wie auch immer, ich habe Sakamotos Workaround benutzt und es funktioniert jetzt gut. Aber vielen Dank für Ihre Hilfe!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X