new aligned



  • Hi,
    ich brauche eine Möglichkeit, um dynamischen Speicher aligned (also an einem entsprechenden Vielfachen ausgerichetet) zu reservieren. Es muss nicht grundsätzlich portabel sein, sollte aber mit dem MSC und GCC funktionieren. Hat jemand 'ne Idee wie man sowas realisieren könnte?



  • Weiß nicht, ob dir das was nützt, aber die Funktion operator new() liefert grundsätzlich Speicher zurück, der passend für jeden denkbaren Datentyp ausgerichtet ist.



  • Hallo,

    naja der operator new gibt ja speicher aligned zurück. Weiss ja nicht welches alignement du brauchst. Evtl. nen Memorypool verwenden.?



  • Wenn dus für SSE (sprich 16 byte aligned) brauchst, bei msvc: _mm_malloc.

    Für gcc gibt es void * memalign(boundary, size);, funzt sonst wie malloc.

    Was auch funktionieren KÖNNTE, hier die gcc version:

    typedef aligned_int int __attribute__((aligned(16)));
    aligned_int * foo = new aligned_int[300];
    

    Hab allerdings weder einen begründeten Verdacht noch eine Garantie, das das funzt.

    Ansonsten, die einfachste Lösung, sogar portabel:

    #define BOUNDARY 16 // oder was auch immer
    typedef type int; // oder was immer man will
    int overhead = BOUNDARY / sizeof(type); 
    // wenn man ein boundary wählt, bei dem BOUNDARY % sizeof(type) != 0, ist man eh beknackt 
    int * orig = new type[anzahl_elemente + overhead];
    void * temp = static_cast<void*>(orig + overhead); // ist nötig wegen pointerarithmetik
    int * aligned = static_cast<type*>(temp - temp % BOUNDARY);
    

    ⚠ Nicht getestet.

    So arbeitet eigentlich auch memalign.
    Aber bitte nicht vergessen delete nachher auf orig anzuwenden, sonst aua.

    so long



  • Bashar schrieb:

    Weiß nicht, ob dir das was nützt, aber die Funktion operator new() liefert grundsätzlich Speicher zurück, der passend für jeden denkbaren Datentyp ausgerichtet ist.

    Sollte man eigentlich meinen. Irgendwie kriegt das mein Compiler aber nicht hin.

    ChockoCookie schrieb:

    Wenn dus für SSE (sprich 16 byte aligned) brauchst

    Yep, genau dafür brauch ichs.

    Mal kurz was zur Struktur:

    class A
    {
        // ist eine Vektorklasse und benutzt die SSE Intrinsics
        // wird entsprechend ausgerichtet (__declspec(...) für MSC und __attribute__(...) für GCC)
    };
    
    class B
    {
        // ...
        A a;
        // ...
    };
    
    class C
        : public B
    {
        // ....
    };
    

    C wird nun per new dynamisch reserviert. Leider scheint mein Compiler (bisher nur mit MSC getestet) die Ausrichtung von A zu ignorieren. B::a findet sich letztendlich an einer Adresse wieder, die auf 8 Byte ausgerichtet ist. Seltsamerweise richtet der MSC an 16 Byte aus, wenn A nicht auf 16 sondern 32 Byte ausgerichtet wird. 😕

    Eigentlich wollte ich in A einen überladenen new und delete Operator implementieren, der das Alignment sicherstellt. Nur bin ich mir nicht sicher, ob das über die Klassenhierarchie hinweg funktioniert. Ausserdem hab ich nur das _mm_malloc für den MSC gefunden. Danke erst mal mit dem memalign Tipp für den GCC.
    Ob mir deine 2. Lösung was nützt, da bin ich mir auch noch nicht sicher. Werd jedenfalls mal 'n bissl mit den verschiedenen Möglichkeiten rumspielen und meine Erkenntnisse hier posten.


Anmelden zum Antworten