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

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Как сделать оптимизацию  (Прочитано 16239 раз)
SubaroMows
Гость
« : Апрель 09, 2012, 20:18 »

Имею дело с матрицами размером 20 x 1000000, по сути в этой матрице храню -1 или 1.(бинарные изображения).
Хотелось бы спросить, какую структуру выбрать для представления этой матрицы, чтобы работало быстрее.

Пока остановился на quint8[][]
Записан
V1KT0P
Гость
« Ответ #1 : Апрель 09, 2012, 20:19 »

Имею дело с матрицами размером 20 x 1000000, по сути в этой матрице храню -1 или 1.(бинарные изображения).
Хотелось бы спросить, какую структуру выбрать для представления этой матрицы, чтобы работало быстрее.

Пока остановился на quint8[][]
Смотря как ты их будешь обрабатывать. Думаю лучше всего quint32 для 32 битных систем и quint64 для 64 битных.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #2 : Апрель 09, 2012, 20:26 »

почему бы не использовать тип bool для уменьшения потребления памяти?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
V1KT0P
Гость
« Ответ #3 : Апрель 09, 2012, 20:30 »

почему бы не использовать тип bool для уменьшения потребления памяти?
Если ему надо делать тяжелые операции, то вытягивание одного бита может дорого стоить.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Апрель 09, 2012, 20:54 »

почему бы не использовать тип bool для уменьшения потребления памяти?
Это скользкое дело - bool может быть и 4 байта (замешан компилятор, за это получал когда переходили на Xcode)

Имею дело с матрицами размером 20 x 1000000, по сути в этой матрице храню -1 или 1.(бинарные изображения).
Хотелось бы спросить, какую структуру выбрать для представления этой матрицы, чтобы работало быстрее.

Пока остановился на quint8[][]
Если хранятся бинарные данные - то и хранить их надо бинарно (в виде битов). А с матрицей надо подровняться на строку. Итого

Код
C++ (Qt)
struct CBinMatrix {
CBinMatrix (int row, int col )  // row = 100000, col = 20
{
  mColBytes = (col + 7) / 8;
  mRow = row;
  mData = new unsigned char[mColBytes * mRow);
}
 
~CBinMatrix( void )
 {
   delete [] mData;
 }
 
bool Get( int row, int col ) const
{
  unsigned char src = *(mData + row * mColBytes + col / 8);
  return (src & (1 << (col % 8))) != 0;
}
 
bool Set( int row, int col. bool val )
{
// напишите по образцу Get
}
 
// data
size_t mColBytes. mRow;
unsigned char * mData;
};
 

почему бы не использовать тип bool для уменьшения потребления памяти?
Если ему надо делать тяжелые операции, то вытягивание одного бита может дорого стоить.
Ой  Улыбающийся

Edit: пропустил сдвиг, подправил
« Последнее редактирование: Апрель 10, 2012, 15:04 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Апрель 09, 2012, 21:49 »

Цитировать
Код
C++ (Qt)
bool Get( int row, int col ) const
{
  unsigned char src = *(mData + row * mColBytes + col / 8);
  return (src & (col % 8)) != 0;
}
 
Да, это конечно же, будет быстрый доступ к элементу)

Опять смайлик забыл поставить..  Улыбающийся
« Последнее редактирование: Апрель 09, 2012, 21:56 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Апрель 10, 2012, 05:21 »

Да, это конечно же, будет быстрый доступ к элементу)

Опять смайлик забыл поставить..  Улыбающийся
Хз что Вы хотели этим сказать - то ли действительно быстрый, то ли изображаете "сарказм знатока"  Улыбающийся  На всякий случай поясню. Обращение к двумерному массиву примерно равно такому коду
Код
C++ (Qt)
*(data + row * mColBytes + col);   // data[row][col]
 
Все равно умножение, сложение потом инкремент указателя. Сравнивая этот вариант с предыдущим - да, у того на неск действий больше, но каждое из них - практически одна машинная команда. Вес операций доступа не так уж велик, поэтому брать в 8(!) раз больше памяти чтобы ускориться на пару процентов - никак не правильно. Не то это место где выжимать скорость
Записан
SubaroMows
Гость
« Ответ #7 : Апрель 10, 2012, 10:20 »

Igors, спасибо. Сделаю замеры по времени работы вышей структуры и просто массива. Выложу результаты
Записан
V1KT0P
Гость
« Ответ #8 : Апрель 10, 2012, 12:16 »

Igors, спасибо. Сделаю замеры по времени работы вышей структуры и просто массива. Выложу результаты
Я вот тут сделал замеры(просто перебор всех значений):
Массив
CBinMatrix
bool to bool
uint8 to bool
quint32 to bool
uint8 to uint8
uint32 to uint32
Затраченное время
0.055737
0.0408991
0.0408365
0.0408429
0.00579459
0.00578789
Отношение к самому быстрому
9.5
7
7
7
1
1
Как я и говорил приведение к биту довольно таки тяжелая операция, в данном случае замедлила все в 7 раз. Самодельная структура так вообще почти в 10 раз медленее тупого массива.
Странно что разницы между uint8 и uint32 нету.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Апрель 10, 2012, 12:27 »

Как я и говорил приведение к биту довольно таки тяжелая операция, в данном случае замедлила все в 7 раз. Самодельная структура так вообще почти в 10 раз медленее тупого массива.
Странно что разницы между uint8 и uint32 нету.
Интересно, только выложите проект. Меня удивляет откуда "bool to bool" 7  Непонимающий
Записан
V1KT0P
Гость
« Ответ #10 : Апрель 10, 2012, 12:39 »

Как я и говорил приведение к биту довольно таки тяжелая операция, в данном случае замедлила все в 7 раз. Самодельная структура так вообще почти в 10 раз медленее тупого массива.
Странно что разницы между uint8 и uint32 нету.
Интересно, только выложите проект. Меня удивляет откуда "bool to bool" 7  Непонимающий
Ну там массив bool и результирующая переменная bool.
Можно попробовать еще какие-то варианты =).
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Апрель 10, 2012, 14:29 »

Тест какой то неадекватный..

Согласен лишь с тем, что вариант Igors будет в любом случае самым медленным.

Да и ещё, можно сравнить c std::vector<dool>. Для bool у вектора написана специализация, оптимизированная под все эти операции. Думаю с вектором получатся самые лучшие характеристики.
Но это нужно проверять... На нормальных тестах) 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
V1KT0P
Гость
« Ответ #12 : Апрель 10, 2012, 14:34 »

Тест какой то неадекватный..
Чем это неадекватный? Тестируется скорость доступа к элементу, что тут неадекватного?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #13 : Апрель 10, 2012, 14:42 »

Цитировать
Чем это неадекватный? Тестируется скорость доступа к элементу, что тут неадекватного?
Во-первых нафига для этого прикручивать Qt гуй? К тому же всё равно прога работает только под виндос.. Обидно..
Во-вторых:
сравним вариант для binMatrix
Код
C++ (Qt)
Timer timer;
   CBinMatrix binMatrix(ROWS, COLS);
   bool d = false;
   timer.Init();
   for (size_t i=0; i<ROWS; i++) {
       for (size_t k=0; k<COLS; k++) {
           d += binMatrix.Get(i, k);
       }
   }
   double delta = timer.GetDelta();
   qDebug() << d << "BinM " << delta;
 

с вариантом:
Код
C++ (Qt)
Timer timer;
   bool **matrix = new bool*[ROWS];
   for (size_t i=0; i<ROWS; i++)
       matrix[ROWS] = new bool[COLS];
   bool d = false;
   timer.Init();
   for (size_t i=0; i<ROWS; i++) {
       for (size_t k=0; k<COLS; k++) {
           d += matrix[ROWS][COLS];
       }
   }
   for (size_t i=0; i<ROWS; i++)
       delete matrix[i];
   delete *matrix;
   double delta = timer.GetDelta();
   qDebug() << d << "bool " << delta;
 

В последним варианте учитывается ещё время на уничтожение массива, в то время, как в первом варианте, при замере времени, массив ещё был жив и разрушится уже после.

В-третьих..

Короче, лучше переписать это нормально, без всяких привлечений "windows.h" и вообще гуя...  

Да, и ещё:
Лучше удалять массив так:
Код
C++ (Qt)
for (size_t i=0; i<ROWS; i++)
       delete []matrix[i];
delete []matrix;
 
   
« Последнее редактирование: Апрель 10, 2012, 14:46 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Апрель 10, 2012, 15:01 »

Ну там массив bool и результирующая переменная bool.
Можно попробовать еще какие-то варианты =).
Не могу откомпилить на своей платформе (не имею windows.h). Ладно, вот мой тест, у меня (icc release) печатает

Цитировать
TestMatr
fill with qrand time = 5.97 s                     // заполнить случайными 0/1
fill time = 0.82 s                                     // заполнить чередующимися 0/1
sum = 167772160, read time = 0.41 s     // сумма всех элементов
sumNear = 364904216, time = 3.13 s      // сумма матриц 3x3

TestArray
fill with qrand time = 5.88 s
fill time = 0.38 s
sum = 167772160, read time = 0.10 s
sumNear = 364904332, time = 1.43 s
Я оцениваю это дело так: когда идет "только (голое) обращение" - массив быстрее в 4 раза (хотя и не в 10). Но как только вмешивается др код - зффект быстро исчезает. Напр sumNear складывает всех соседей пикселя - вроде тоже обращение, добавлены лишь проверки на границы. Тем не менее выигрыш уже только в 2 раза. А вызов скромного qrand вообще убивает в ноль.

Также возможно что при бОльших размерах данных (сотни мегабайт) битовые данные будут "просто быстрее" за счет того что используемый диапазон адресов меньше (дела кэша)
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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