Results 1 to 11 of 11

Thread: Memory aligned QVector().data()

  1. #1
    Join Date
    Nov 2010
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Memory aligned QVector().data()

    Hello there. I'm using some SSE optimizations on a large QVector and I need the QVector().data() pointer to be 16-byte memory aligned. My code goes something like this:

    Qt Code:
    1. QVector *vec = new QVector ();
    2.  
    3. if(((uintptr_t)vec->data() & 0x0F) == 0) {
    4. // great, we got memory aligned data
    5. }
    6. else {
    7. // try again or use backup code
    8. }
    To copy to clipboard, switch view to plain text mode 

    My code works but whether I can use optimizations is completely random and so far I couldn't find a way to make QVector acquire a memory aligned data pointer. Any ideas?

  2. #2
    Join Date
    Sep 2010
    Posts
    145
    Thanks
    1
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    This isn't really a Qt question, but about fundamental c++. That is: operator overloading, and more specifically operator new.

  3. #3
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    you might find this interesting.
    Its not about QVector, but I think the problematics, and solutions are probably similar if not the same.
    http://ompf.org/forum/viewtopic.php?f=11&t=686
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  4. #4
    Join Date
    Nov 2010
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    @ Timoteo - Not so.

    On one hand QVector uses the malloc/free functions for the memory allocation of its internal array (which is of type QVectorTypedData<T> -> check "qvector.h") and the way it aligns the memory is specified (as in "it's not your default malloc"; it does some memory alignment, just not the one I want).

    On the other hand modifying the Qt source code to force a specific alignment is not an option so I was wondering if there were any other options available instead of using hacks.

    So no, it's definitely not a C++ question.

    @high_flyer - thank you for the link, unfortunately my problem is directly related to Qt because I want to use QVector's functionality. I dug a bit through Qt's sources and if I find anything worthwhile I'll post it here.

  5. #5
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    On the other hand modifying the Qt source code to force a specific alignment is not an option so I was wondering if there were any other options available instead of using hacks.
    You can Subclass QVector.

    unfortunately my problem is directly related to Qt because I want to use QVector's functionality.
    Yes, but the problematic in the link and yours are the same.
    They have a problem with how std::vector aligns (or rather not) its data, yours is with QVector.

    So I think to Timoteo is not that wrong - you need to add code to align your data in QVector the way you need it.
    I agree that Overloading new would be too much, but a special "allocAlignedQVector()" or subclassing QVector to QAlignedQVector where you implement this will be in place.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  6. #6
    Join Date
    Nov 2010
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    The problem is not the same. For std::vector you can create custom memory allocators that do the job ; I am not aware of such functionality for QVector. Unfortunately the problem is particular to Qt.

    As far as I can see inheriting from QVector does not work; the data is stored in a QVectorData object (which also has the functions for all memory allocation) that is -of course- private so I can't touch it.

    Overloading new doesn't seem to solve anything because neither QVector nor QVectorData use it internally (they do use in-place new but that's useless, the memory is already malloc-ed).
    Last edited by sto; 18th November 2010 at 11:37. Reason: I accidentally a word.

  7. #7
    Join Date
    Sep 2010
    Posts
    145
    Thanks
    1
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    Yea, I was referring to defining an operator new for your contained types, but you say that QVector uses C-style allocations internally. Is QVector::fromStdVector feasible? I haven't looked at the source for it, so you may end up with the same situation.

  8. #8
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Memory aligned QVector().data()

    QVector::fromStdVector() copies the data from the standard vector, so alignment will not be preserved.

    I'd be inclined to use std::vector with a custom allocator myself. Something along these lines: http://stackoverflow.com/questions/2...-for-stdvector

  9. #9
    Join Date
    Nov 2010
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    Just to clarify - I could use std::vector and everything would work fine but for the sake of uniformity (using Qt throughout the whole project) and science I wanted to know if it could be done in Qt. Two things:

    1) I want to use a QVector<float> but that only creates a memory alignment of sizeof(float), which in my case is 4 (SSE needs 16 to work at its best). I could use a hack such as

    Qt Code:
    1. typedef union {
    2. __m128 stub; // sizeof(__m128) == 128 ; // 16 bytes
    3. float f[4];
    4. } float4;
    5.  
    6. QVector<float4> vec;
    7.  
    8. Q_ASSERT( ((uintptr_t)vec.data() & 0xF) == 0); // always zero
    To copy to clipboard, switch view to plain text mode 

    but this creates extra complexity because I don't always want to store a number of values that's a multiple of 4.


    2) Here's a part of the QVector::append() function.

    Qt Code:
    1. template <typename T>
    2. void QVector<T>::append(const T &t)
    3. {
    4. ...
    5. if (QTypeInfo<T>::isComplex)
    6. new (p->array + d->size) T(copy);
    7. ...
    8. }
    To copy to clipboard, switch view to plain text mode 

    It uses in-place new, specifying the memory address QVector expects for my value to have. I could use some hacks here as well (use a custom type, overload in-place new, etc) but this is much more complex than simply using another container.

    I guess there's no easy way to make Qt use custom memory alignment but if I find anything I'll let you know. Thanks for the help.

  10. #10
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    Just a comment:
    From the wikipedia definition:
    A memory address a, is said to be n-byte aligned when n is a power of two and a is a multiple of n bytes.
    conflicts with your statement:
    I don't always want to store a number of values that's a multiple of 4.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  11. #11
    Join Date
    Nov 2010
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Memory aligned QVector().data()

    I don't always want to store a number of values [inside my vector] that's a multiple of 4.
    There, that should make things more clear. My statement is related to the hack where each element of the vector stores 4 floating point values instead of just one so that QVector gives the proper data alignment.

    If it's still not clear I'll quote this as well:
    ...I need the QVector().data() pointer to be 16-byte memory aligned
    QVector allocates a contiguous memory region for its values and the pointer resulted from that memory allocation needs to be 16-byte memory aligned. The memory alignment has nothing to do with the number of elements inside the vector.

    I simply want QVector<float> to return a 16-byte aligned data pointer but it won't because sizeof(float) == 4 (in my case) and not 16. Actually things get more complicated because Qt seems to use the Q_ALIGNOF macro to determine the alignment. So, for example, regular 32-bit code:

    Qt Code:
    1. struct test0 { float f;};
    2. struct test1 { float f; double d;};
    3. struct test2 { float f[4]; };
    4. union test3 { float f[4]; __m128 spfp; };
    5.  
    6. qDebug() << sizeof(test0) << Q_ALIGNOF(test0);
    7. qDebug() << sizeof(test1) << Q_ALIGNOF(test1);
    8. qDebug() << sizeof(test2) << Q_ALIGNOF(test2);
    9. qDebug() << sizeof(test3) << Q_ALIGNOF(test3);
    To copy to clipboard, switch view to plain text mode 

    For Visual Studio Q_ALIGNOF defaults to the __alignof operator, I assume that the same behavior is used for all compilers. The first qDebug value outputs the size of the structure/union and the second value gives you the alignment Qt decides to use. Output goes as follows:

    Qt Code:
    1. 4 4 // on my machine sizeof(float) == 4 and sizeof(double) == 8
    2.  
    3. 16 8 // sizeof is 16 (8 + 4 + (extra 4 padding, bonus from Visual C++))
    4. // Q_ALIGNOF returns the largest data type (double)
    5.  
    6. 16 4 // sizeof is 16 (4 floats)
    7. // Q_ALIGNOF returns only the base data type's sizeof, which is 4
    8.  
    9. 16 16 // sizeof is 16 and Q_ALIGNOF sees the __m128 and returns 16; unfortunately now I'm forced to store 4 values at once (even if I only need 1, 2 or 3; so a QVector using this type would always store a multiple of 4 floating point values)
    To copy to clipboard, switch view to plain text mode 
    Last edited by sto; 19th November 2010 at 09:49. Reason: clarification

Similar Threads

  1. Painting a right-aligned text
    By curreli in forum Newbie
    Replies: 2
    Last Post: 29th July 2010, 16:49
  2. [[SOLVED]]Can't get data from QVector
    By asieriko in forum Newbie
    Replies: 1
    Last Post: 13th December 2009, 19:55
  3. QVector::data() and implicit sharing
    By abernat in forum Qt Programming
    Replies: 2
    Last Post: 7th July 2009, 18:34
  4. Memory allocation failure and crash in QVector
    By ashatilo in forum Qt Programming
    Replies: 16
    Last Post: 20th October 2007, 23:27
  5. Replies: 1
    Last Post: 12th November 2006, 16:56

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.