Russian Qt Forum

Qt => Общие вопросы => Тема начата: Akon от Февраль 17, 2014, 10:18



Название: QVector с выровненными данными
Отправлено: Akon от Февраль 17, 2014, 10:18
Как известно, в контейнерах Qt нет аллокаторов в отличие от STL. Мне нужно выравнивание данных, например, чтобы было
&vector[0] % 16 == 0.
Какие будут соображения?


Название: Re: QVector с выровненными данными
Отправлено: OKTA от Февраль 17, 2014, 10:35
Код:
typedef union {
    __m128 stub;  // sizeof(__m128) == 128 ; // 16 bytes
    float f[4];
} float4;
 
QVector<float4> vec;
 
Q_ASSERT( ((uintptr_t)vec.data() & 0xF) == 0);    // always zero

Вроде хорошая идея)
Украдено в http://www.qtcentre.org/threads/36090-Memory-aligned-QVector()-data()


Название: Re: QVector с выровненными данными
Отправлено: Igors от Февраль 17, 2014, 13:17
Делать pad'ы, вставлять заполнители чтобы размер был кратен 16

Код:
 typedef union {

Вроде хорошая идея)
Это натолкнется на сообщение типа "union can not have non-trivial members"

Edit:
Как известно, в контейнерах Qt нет аллокаторов в отличие от STL.
А что Вам даст аллокатор если (по определению) std::vector должен приводиться к С-массиву?


Название: Re: QVector с выровненными данными
Отправлено: Akon от Февраль 17, 2014, 20:07
OKTA: в плане выравнивания работать должно, спасибо. Только неудобно будет... vector.begin() + 1 куда покажет?

Цитировать
А что Вам даст аллокатор если (по определению) std::vector должен приводиться к С-массиву?
Перефразирую свой вопрос: мне нужен массив char'ов, начинающийся с адреса, кратного 16-ти.



Название: Re: QVector с выровненными данными
Отправлено: Igors от Февраль 18, 2014, 06:15
Перефразирую свой вопрос: мне нужен массив char'ов, начинающийся с адреса, кратного 16-ти.
То есть хранить в нем объекты/классы задача не стоит. В open-sources видел типа такого: сначала проверяется поддерживается ли платформой _aligned_malloc. Если нет, то все по-старинке: распределяем блок (+16) и отдаем кратный начальный адрес. Ну или просто QVector <char> и при приведении у массиву подровняться. 


Название: Re: QVector с выровненными данными
Отправлено: Old от Февраль 18, 2014, 07:57
Перефразирую свой вопрос: мне нужен массив char'ов, начинающийся с адреса, кратного 16-ти.
А добавлять в вектор значения нужно будет или он будет статичен? При переаллокации он новый кусок памяти сам выравнивать не будет.


Название: Re: QVector с выровненными данными
Отправлено: Akon от Февраль 18, 2014, 13:10
В нутрях QVеctor пользует некую qAlignedAllloc (могу ошибиться с точным названием), одним из аргументов которой идет размер выравнивания, определяемый в свою очередь из свойств типа элемента. Поэтому, для _mm16 там всегда должно идти 16 при любом сценарии использования вектора.

Если говорить об универсальном и удобном решении (приведенный выше вариант не удобен в использовании), то необходимо завести пользовательский тип, размер которого равен размеру желаемого типа (например, char), но с задаваемым выравниванием. Вариант MSVC:

Код:
	// aligned_32_char

__declspec(align(32)) class aligned_32_char
{
public:
aligned_32_char(char data = 0) : data_(data) {}
operator char() { return data_; }
                             ...

private:
char data_;
};

QVector<aligned_32_char>  v(1);
std::cout << (void*)&v[0] << std::endl;

char elem = v[0];  // operator char()
v[0] = 7;          // non-explicit ctor

Код:
v[1] -> points to 17-th byte, вообщем, таже песня, неудобно.


Название: Re: QVector с выровненными данными
Отправлено: Igors от Февраль 18, 2014, 13:49
Если говорить об универсальном и удобном решении (приведенный выше вариант не удобен в использовании), то необходимо завести пользовательский тип, размер которого равен размеру желаемого типа (например, char), но с задаваемым выравниванием. Вариант MSVC:
Значит есть еще и "не MSVC" - где же универсальность и удобство? :) Да и расчет только на QVector. Qt ничего нового не изобретает - тоже выделяет с запаской, потом, если нужно, подгоняет/подделывает указатель (qMalloc.cpp)


Название: Re: QVector с выровненными данными
Отправлено: Old от Февраль 18, 2014, 14:13
Qt ничего нового не изобретает - тоже выделяет с запаской, потом, если нужно, подгоняет/подделывает указатель (qMalloc.cpp)
А тут можно что-то новое изобрести? :)


Название: Re: QVector с выровненными данными
Отправлено: Akon от Февраль 18, 2014, 14:47
Цитировать
Значит есть еще и "не MSVC" - где же универсальность и удобство?
MSVC у меня под рукой, и я просто накидал это решение. А так в GCC будет аналогичная директива и т.д.


Название: Re: QVector с выровненными данными
Отправлено: Igors от Февраль 18, 2014, 15:14
А тут можно что-то новое изобрести? :)
Нет конечно, главное не увлечься. Сейчас переделываю код др программиста который очень любил выделять память блоками знающими собственный размер. Мда..  :'(


Название: Re: QVector с выровненными данными
Отправлено: Old от Февраль 18, 2014, 15:15
который очень любил выделять память блоками знающими собственный размер. 
Это как?


Название: Re: QVector с выровненными данными
Отправлено: Igors от Февраль 18, 2014, 15:21
Это как?
Та точно так же: распределил + параграф куда записал длину, отдал адрес + 16, на удалении -16


Название: Re: QVector с выровненными данными
Отправлено: Old от Февраль 18, 2014, 15:33
Та точно так же: распределил + параграф куда записал длину, отдал адрес + 16, на удалении -16
А смысл? Где он этот размер использовал?


Название: Re: QVector с выровненными данными
Отправлено: stalker от Февраль 21, 2014, 10:42
Как известно, в контейнерах Qt нет аллокаторов в отличие от STL. Мне нужно выравнивание данных, например, чтобы было
&vector[0] % 16 == 0.
Какие будут соображения?
Don't warry! Be happy!
Стандарт C++11 предоставляет прекрасные возможности:
Код:
// выравнивание по 16 байтной границе
alignas(16) char[100];

Пруф (http://sergeyteplyakov.blogspot.com/2012/05/c-11-faq.html#align)


Название: Re: QVector с выровненными данными
Отправлено: Akon от Февраль 21, 2014, 14:06
Это не то. Вопрос касается динамически распределяемой памяти, а не стековой и не статической.
Код:
// требуется нечто в этом роде (псевдокод):
alignas(16) char* c_ptr = new alignas(16) char[100];


Название: Re: QVector с выровненными данными
Отправлено: stalker от Февраль 21, 2014, 16:01
Это не то. Вопрос касается динамически распределяемой памяти, а не стековой и не статической.
Код:
// требуется нечто в этом роде (псевдокод):
alignas(16) char* c_ptr = new alignas(16) char[100];
По определению, объектами в динамической памяти управляет не компилятор, а программист.
Следовательно, для достижения эффекта выравнивания в динамической памяти нужно написать свой аллокатор.
Компилятор тут не помощник.


Название: Re: QVector с выровненными данными
Отправлено: Akon от Февраль 21, 2014, 16:45
Теперь вижу, вы поняли суть вопроса :)