Wie erzeuge ich ein performantes 2Dim-Array von Primitiven (double, int) ?

  • Wie erzeuge ich ein performantes 2Dim-Array von Primitiven (double, int) ?

    Hallo liebe Leute,

    das ist mein erster Beitrag in diesem Forum. Ich habe vor 2 Wochen zum ersten mal angefangen mit Objective-C zu arbeiten. War kein Muss, aber da ich nunmal auf MAC umgestiegen bin, wollte ich auch Objective-C lernen. Ich habe im Grunde 2-3 Probleme, da ich bisher nur mit JAVA wirklich programmiert habe, habe ich noch kein tiefsitzendes Gefühl für das Zeigerkonzept der ganzen C-Sprachen. (Obwohl ich 2 Semester OpenGL mittels C++ programmieren musste)

    Nun zu meinem eigentlichen Problemen:
    Im Rahmen meiner Dipl-Arbeit beschäftige ich mich mit neuronalen Netzen und dafür muss ich mit Daten aus Messdateien Matrizen und Vektoren aufstellen und dann im wesentlichen Lineare Algebra betreiben also Matrizen/Vektoren mit einander multiplizieren und addieren. Und nun stehe ich da vor 3 Problemstellungen:
    1. Ich muss die Daten aus der Datei lesen aber dann erst zur Laufzeit mittels eines GUI bestimmen welche der Daten in Matrizen/Vektoren gestopft werden um berechnet zu werden. Also muss ich meine 2-Dim-Arrays zur runtime allokieren. (das sind alles doubles) Was benutze ich da denn am besten. Ich versuche es gerade mit einem Array[Array[double]] wie ich es in C++ gemacht habe, weiß aber nicht ob das klappt. also sowas wie

      Quellcode

      1. double **Matrix;
    2. Ich hab gelesen, dass für solche zwecke die vecLib gut geeignet sein soll und auch sehr schnell ist, aber ich finde kein Tutorial um mich mal einzuarbeiten in die Funktionsweise von vecLib und dem Accelerate Framework... weiß da vielleicht einer was?
    3. Im Zusammenhang mit der vecLib habe ich mir gedacht, dass ich die Daten an sich aus der Datei in eine CoreData Bibiothek einlesen sollte um Sie dort zu verwalten und zum berechnen aus diesen Daten der CoreData dann entsprechend Matrizen/Vektoren erstellen sollte. Ist das ein vernünftiger Ansatz?
    An alle die soweit gelesen haben schon mal ein großes Dankschön. Und ein zweites Danke an die die versuchen mich in die richtige Richtung anzuschieben.
    Es wird nichts so heiß gegessen wie es gekocht wird.
  • RE: Wie erzeuge ich ein performantes 2Dim-Array von Primitiven (double, int) ?

    Zunächst eine Frage: Liegt die Dimension der Matrizen und Vektoren zur Übersetzungszeit bereits fest? Dann wäre es ja einfach.

    Wenn dies nicht der Fall ist, kannst du auf Cocoa-Arrays ausweichen (NSArray, NSMutableArrays) oder eben C-Arrays, die etwas sperriger sind. Templates alla C++ existieren nicht.

    Wenn du aus nahe liegenden Gründen die vecLib verwenden möchtest: Hast du dieses hier schon gesehen;
    developer.apple.com/documentat…/Reference/reference.html
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Hallo,

    kennst du schon: eigen.tuxfamily.org/index.php?title=Main_Page

    Allerdings kannst du natürlich auch versuchen bei Objective-C zu bleiben. Ein zwei-dim-NSArray kann so langsam nicht sein...

    Bevor du dich auf eine "Sprache" stürzt wäre es vielleicht eine gute Idee einen Use-Case in Objective-C und C++ zu programmieren und zu bewerten. Wobei ich mir sicher bin, dass man auch mit Objective-C "hoch performant" lineare Algebra betreiben kann.

    Gerade bei der linearen Algebra hat der eingesetzte Algorithmus einen viel höheren Einfluss auf die Performance als die Programmiersprache selbst...
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • Nein Dimension wird erst zur Laufzeit berechnet

    Die Dimension wird erst zur Laufzeit bestimmt aus Eingaben die man im GUI macht. Des wegen wären natürlich vector<Template> wirklich ideal! Aber naja! Dann muss ich mich halt in NSArrays einlesen.
    ---> Ein Problem, was ich damit habe ist, dass ich bisher nur Beispiele gesehen habe in denen wirklich mit primitiven die vecLib Methoden gefüttert werden. Also soetwas

    Quellcode

    1. float outVector[8] __attribute__ ((aligned));

    Ich weiß nicht ob das auch mit NSArray gehen wird.... Und der wichtigste Punkt ist halt die Schnelligkeit, da ich im nächsten schritt ohne GUI einfach nur die Eingangsparameter und Dimensionen des neuronalen Netzes variieren möchte und sehen wie sich das auf Laufzeit und Ergebnisstabilität auswirkt.
    Es wird nichts so heiß gegessen wie es gekocht wird.
  • RE: Nein Dimension wird erst zur Laufzeit berechnet

    Du kannst freilich C++ und Objective-C mischen. Und mit dem neuen Run-Time geht das sogar vernünftig (Stichwort: Exceptions).

    In deine Falle klingt das aber fast so, als ob man eine Foreground-App in Objective-C und einen Background-Prozess in C/C++/InersertYourPreferenceHere machen kann.

    Ich nehme mal an, dass das neuronale Netz einfach nur massiv rechnet.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Ich will nicht nach Jüllich :-)

    Nun es ist natürlich nicht so, dass ich so riiiiiiesige Datensätze hätte, dass ich Rechenzeit in Jüllich beantragen müsste. Aber da ich mich damit befasse, wollte ich versuchen auch einen effizienten Weg zu finden.

    Und im Endeffekt will ich dabei ja auch lernen. Wenn Ihr sagt, NSArray /NSMutableArray ist gut, dann probier ich es mal damit! Ich denke es wird sich nicht um Mehr als 10 000 bis 100 000 Datensätze handeln. Also alles Sachen die sich in endlichem Zeitaufwand rechnen lassen.

    @anim:
    Es ist im Grunde genau das womit ich eigentlich begonnen habe. Hab mir gedacht ich mache eine Oberfläche mit Cocoa (Da ich auf nem Mac programmiere) und erstelle alle berechnenden und Datenverwaltenden Klassen in C++! Die Klassen hatte eich schon fertig in C++ erstellt. Die liefen auch Fehler und Absturz frei. Aber bei meinem ersten Versuch diese in die Cocoa Oberfläche einzubinden hat mir der Compiler 186 Fehler gemeldet. Da habe ich mich entschieden doch alles aus einem Guss in Objective-C/Cocoa zu machen! Ich komme auch einigermaßen vorwärts.

    Wollte nur mal Fragen ob das was ich da anvisiere überhaupt geeignet ist mit Objective-C. (Ich will mich nicht auch noch in C einarbeiten)

    BTW:
    Persönlich bevorzuge ich Sprachen wie Java die einem die Verwaltung abnehmen. Ich mag nicht mit Pointern hantieren. Und die TreeSets, Vectoren und anderen Strukturen von Java waren auch wie ich finde verdammt leistungsfähig. Wenn da nicht immer die Runtime von Java an sich noch überall mitlaufen müsste.
    Aber seit wir OpenGL programmiert haben mag ich JAVA nicht mehr. JOGL hat mir das reichlich vermiest. :)
    **Noch eine kleine Bitte! Bitte nicht jedes Wort von mir auf die Goldwaage legen! Ich bin Physiker und nicht der beste Programmierer. Deswegen muss ich euch zuweilen mit meinem geballten Halbwissen konfrontieren. Zumindest liegt mir aber der Wunsch inne mich zu entwickeln und zu lernen :) **


    ---------------------------------------------------------------------------------------------------------------------
    Edit:

    Was ist eigentlich der Unterschied zwischen NSArray und NSMutableArray?
    Es wird nichts so heiß gegessen wie es gekocht wird.
  • RE: Ich will nicht nach Jüllich :-)

    Na, schauen wir mal. Ich meinte allerdings dass du wirklich einen Hintergrundprozess startest, also eine eigenes Programm. Man kann ja mit Hintergrundprogrammen kommunizieren – wenn der Umfang der Kommunikation die Sache nicht tötet.

    NSMutableArray ist einfach eine Subklasse von NSArray, die veränderlich ist. Du kannst also Elemente des Arrays löschen, einfügen und austauschen, was bei NSArray nicht geht. Aber bedenke: Dadurch, dass Objekte immer referenziert werden, können natürlich auch bei einem NSArray die Elemente selbst verändert werden. Da ich mal mutmaße, dass du während der Simulation keine Knoten hinzufügen oder ändern willst, dürfte dir NSArray ausreichen. (Bei der Erzeugung wirst du mutmaßlich ein Mutable-Array benötigen, dass du beim Start aber in ein NSArray kopieren kannst.)

    In ein Array kannst du nur Instanzen stopfen, also keine Integer & Co.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Du solltest vielleicht auch in Erwaegung ziehen, eine eigens dafuer vorgesehen Library zu verwenden, die auf Aufgaben der Linearen Algebra spezialisiert ist. Die muss ja auch nicht zwingend Obj-C sein, Du kannst ja wirklich relativ problemlos C-Libs in deinem Objective-C code verwenden.

    Ich habe bisher nur BLAS (und auch nur fuer CUDA und unter Windows) verwendet, aber hier werden Dir schon Matrizen und Operationen darauf bereitgestellt. Wobei BLAS wiederum standard C Arrays/Speicherverwaltung nimmt, in der Referenz-Doku ist aber erklaert wie.

    Die GNU Scientific Library wollte ich immer mal probieren (ich mag nur die Lizenz nicht), dort werden aber wohl eigene Datentypen zur Verfuegung gestellt.

    Ich weiss ja nicht, was Du dann genau machen willst, aber i.d.R. sollte man die meissten numerischen Algorithmen nicht selber implementieren, sofern man kein Mathematiker ist (wegen Stabilitaet etc.)

    Noch etwas zu Arrays etc:
    Je nach Groesse und Verarbeitungsweise Deiner Matrizen ist es wichtig, wie diese im Speicher abgelegt sind, so dass Du nicht andauernd Cache-Misses erzeugst. Gleich nach der Wahl der Algorithmen steht meines Erachtens schon das Cache-Verhalten als wichtigster Punkt was Performance angeht.
    C++
  • Ein Kompromiss wären noch die STL-C++-Klassen, die verhalten sich aus Anwendersicht ähnlich wie C-Arrays sind aber sicherer und mächtiger (std:vector) und Du kannst sie einfacher z.B. in evtl. schon vorhandenem OpenGL-Code benutzen (Vektor-Arrays für Vertexbuffer u.ä., wo sich die Cocoa-Container nicht direkt verwenden lassen, das hängt natürlich von Deinen Anforderungen ab).

    Solltest Du C++ und Objective-C Code mischen wollen, musst Du u.U. die Dateien mit .mm enden lassen, damit der Compiler den Mischcode erkennt (Du schriebst von 100ten Fehlermeldungen bei Deinem existierenden Code). Kann aber sein, dass die aktuelle Xcode-Version das mittlerweile automatisch erkennt.

    Womöglich auch mal bei Boost vorbeischauen.
    Direkt geschachtelte C-Arrays würde ich nicht verwenden, das ist zu schmerzhaft und fehleranfällig.
    Andererseits wär das natürlich eine prima Gelegenheit, ein Gefühl für die Brot-und-Butter Klassen von Cocoa zu bekommen...
  • Ohne alles gelesen zu haben: wenn Performance wichtig ist und die Größe des Arrays erst zur Laufzeit feststeht, bietet es sich an, C Arrays in ein NSData Objekt zu packen.

    Quellcode

    1. const int valuesCount = ... ;
    2. NSMutableData* valuesData = [NSMutableData dataWithLength:valuesCount * sizeof(float)];
    3. float* values = (float*)[valuesData mutableBytes];
    4. for (int i = 0; i < valuesCount; i++) {
    5. values[i] = ... ;
    6. }
  • Original von konben81
    Ohne alles gelesen zu haben: wenn Performance wichtig ist und die Größe des Arrays erst zur Laufzeit feststeht, bietet es sich an, C Arrays in ein NSData Objekt zu packen.
    […]

    Gute Idee!

    Man könnte auch noch NSValue nehmen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Noch eine Konzeptionsfrage!

    Hallo ein weiteres mal,

    ich hab da noch eine Frage zur Konzeption. Meine Daten sehen im Grunde wie folgt aus:
    Ich habe ein Datei (später auch mehrere) in welcher mehrere Messdurchläufe enthalten sind. Ein Messdurchlauf besteht aus etwa 240 Messpunkten von denen jeder wieder 16 Messwerte enthält.
    Ich dachte daran eine Klasse Messpunkt anzulegen die die 16 Messwerte enthält und vielleicht noch einen Int damit jeder Messpunkt weis zu welchem Messdurchlauf er gehört. Und dann wollte ich einfach alle Messpunkte aus der Datei in ein Array (Nach euren Tipps denke ich ein NSArray. Denn ich kann ja die Anzahl der Messpunkte feststellen und dann das Array fest allokieren.)

    Jetzt wollte ich aber vielleicht später mehrere Dateien behandeln. Soll ich die trotzdem fortlaufend in dieses Array schreiben oder ein Array von Arrays machen?

    Und dann hatte ich da noch ein weiteres Verständnisproblem. Unter Java mache ich einfach nur eine Schleife zum einlesen der Datei und in jedem durchlauf initialisiere ich eine Instanz meiner Klasse, setze Ihre member Variablen und schiebe sie in einen Vector (bzw. Array). Das klappt hier nicht wirklich so straight forward..... Ich hab auch schon ein paar seiten zum release/retain Counter gelesen, aber ich scheine da ein generelles Problem zu haben. Kann mir da einer ein kleines Beispiel so einer Schleife zeigen?
    Es wird nichts so heiß gegessen wie es gekocht wird.
  • das sollte so gehen wie du beschrieben hast. also mit der schleife und dem hinzufügen. was genau funktioniert denn nicht?

    wo wir aber wieder bei dem performant sind: wenn du es speicherst und wieder lädst und das ganze möglichst performant sein soll, dann bleibt man (wie meistens wenn es um performance geht) etwas tiefer. In dem fall kann man zb structs verwenden. die kann man dann einfach einlesen und wieder schreiben. vor allem wenn du zb definierst dass deine files LITTLE-ENDIAN sind und du auf einer solchigen maschine einliest und schreibst. dann fällt sogar das swappen weg.
    Bei den structs musst dem compiler aber noch sagen dass er align-bytes nicht verwenden soll.

    jetzt wirds gleich wieder infos geben dass man das auch mit eigenen objekten machen kann und das das eleganter ist etc aber darum gehts mir ja nicht. Dass das auch so geht ist klar - nur eben nicht so performant ;)