Russian Qt Forum
Ноябрь 25, 2024, 03:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QVector с выровненными данными  (Прочитано 8092 раз)
Akon
Гость
« : Февраль 17, 2014, 10:18 »

Как известно, в контейнерах Qt нет аллокаторов в отличие от STL. Мне нужно выравнивание данных, например, чтобы было
&vector[0] % 16 == 0.
Какие будут соображения?
Записан
OKTA
Гость
« Ответ #1 : Февраль 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()
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Февраль 17, 2014, 13:17 »

Делать pad'ы, вставлять заполнители чтобы размер был кратен 16

Код:
 typedef union {

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

Edit:
Как известно, в контейнерах Qt нет аллокаторов в отличие от STL.
А что Вам даст аллокатор если (по определению) std::vector должен приводиться к С-массиву?
« Последнее редактирование: Февраль 17, 2014, 13:51 от Igors » Записан
Akon
Гость
« Ответ #3 : Февраль 17, 2014, 20:07 »

OKTA: в плане выравнивания работать должно, спасибо. Только неудобно будет... vector.begin() + 1 куда покажет?

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

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Февраль 18, 2014, 06:15 »

Перефразирую свой вопрос: мне нужен массив char'ов, начинающийся с адреса, кратного 16-ти.
То есть хранить в нем объекты/классы задача не стоит. В open-sources видел типа такого: сначала проверяется поддерживается ли платформой _aligned_malloc. Если нет, то все по-старинке: распределяем блок (+16) и отдаем кратный начальный адрес. Ну или просто QVector <char> и при приведении у массиву подровняться. 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Февраль 18, 2014, 07:57 »

Перефразирую свой вопрос: мне нужен массив char'ов, начинающийся с адреса, кратного 16-ти.
А добавлять в вектор значения нужно будет или он будет статичен? При переаллокации он новый кусок памяти сам выравнивать не будет.
Записан
Akon
Гость
« Ответ #6 : Февраль 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, вообщем, таже песня, неудобно.
« Последнее редактирование: Февраль 18, 2014, 15:06 от Akon » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Февраль 18, 2014, 13:49 »

Если говорить об универсальном и удобном решении (приведенный выше вариант не удобен в использовании), то необходимо завести пользовательский тип, размер которого равен размеру желаемого типа (например, char), но с задаваемым выравниванием. Вариант MSVC:
Значит есть еще и "не MSVC" - где же универсальность и удобство? Улыбающийся Да и расчет только на QVector. Qt ничего нового не изобретает - тоже выделяет с запаской, потом, если нужно, подгоняет/подделывает указатель (qMalloc.cpp)
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Февраль 18, 2014, 14:13 »

Qt ничего нового не изобретает - тоже выделяет с запаской, потом, если нужно, подгоняет/подделывает указатель (qMalloc.cpp)
А тут можно что-то новое изобрести? Улыбающийся
Записан
Akon
Гость
« Ответ #9 : Февраль 18, 2014, 14:47 »

Цитировать
Значит есть еще и "не MSVC" - где же универсальность и удобство?
MSVC у меня под рукой, и я просто накидал это решение. А так в GCC будет аналогичная директива и т.д.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Февраль 18, 2014, 15:14 »

А тут можно что-то новое изобрести? Улыбающийся
Нет конечно, главное не увлечься. Сейчас переделываю код др программиста который очень любил выделять память блоками знающими собственный размер. Мда..  Плачущий
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #11 : Февраль 18, 2014, 15:15 »

который очень любил выделять память блоками знающими собственный размер. 
Это как?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Февраль 18, 2014, 15:21 »

Это как?
Та точно так же: распределил + параграф куда записал длину, отдал адрес + 16, на удалении -16
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Февраль 18, 2014, 15:33 »

Та точно так же: распределил + параграф куда записал длину, отдал адрес + 16, на удалении -16
А смысл? Где он этот размер использовал?
Записан
stalker
Гость
« Ответ #14 : Февраль 21, 2014, 10:42 »

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

Пруф
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.133 секунд. Запросов: 22.