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

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

Страниц: 1 ... 3 4 [5] 6 7   Вниз
  Печать  
Автор Тема: Memory issues  (Прочитано 54066 раз)
BRE
Гость
« Ответ #60 : Сентябрь 16, 2009, 13:14 »

И почему мы имеем разные результаты на разных платформах?
Ограничения конкретной платформы.
У BRE работает у меня нет. Что это за кросс-платформенность такая? Обещали по squeeze память освобождать - вот пусть и освобождают.
Если я увеличу количество элементов, у меня возникнут такие же проблемы.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #61 : Сентябрь 16, 2009, 13:20 »

Я уже писал, но повторюсь. Это не проблема Qt, это проблема (а точнее особенность) стратегии менеджера памяти конкретной OS. Тролли эту проблему/особенность обойти не смогут.
Откуда мы с Вами знаем чего они могут/не могут? Мы здесь в роли пользователей, наше дело сообщать
Конечно, можно написать репорт.
Только ответ скорее всего будет один: для конкретной задачи нужно подбирать правильный контейнер, учитывая его особенности.
Ладно, не надо - так не надо  Улыбающийся
Записан
SABROG
Гость
« Ответ #62 : Сентябрь 16, 2009, 13:34 »

И std::list и Qlist не thread-safe.

А написано, что все контейнеры Qt thread-safe.
Цитировать
In addition, they are thread-safe in situations where they are used as read-only containers by all threads used to access them.
« Последнее редактирование: Сентябрь 16, 2009, 13:36 от SABROG » Записан
Winstrol
Гость
« Ответ #63 : Сентябрь 16, 2009, 13:53 »

А написано, что все контейнеры Qt thread-safe.
Цитировать
In addition, they are thread-safe in situations where they are used as read-only containers by all threads used to access them.

Тут идет речь о basic thread-safety. Т.е. безопасных одновременных вызовах const методов. Для list естественно это тоже справедливо, хотя  текущий стандарт языка, частью которого является stl, про потоки ничего не знает.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2669.htm
Цитировать
Thread-Safety in the Standard Library (Rev 2)
...
Basic thread-safety guarantee

The basic thread-safety guarantee  would be that standard library functions are required to be reentrant, and non-mutating uses of objects of standard library types are required to not introduce data races. This has little or no impact on performance. It does actually deliver the promised safety. Thus this basic thread-safety guarantee is required of implementations.
Strong thread-safety guarantee

The strong thread-safety guarantee would be that mutating uses of objects of standard library types are required to not introduce data races. This would have a severe negative impact on performance. Furthermore, real safety often requires locking across several member function calls, so providing per function-call locking would create a illusion of safety that did in fact not exist. For these reasons, a blanket strong thread-safety guarantee for mutating shared objects is not provided, and constraints are put on programs accordingly.
« Последнее редактирование: Сентябрь 16, 2009, 13:56 от Winstrol » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #64 : Сентябрь 16, 2009, 14:04 »

Цитировать
Обещали по squeeze память освобождать - вот пусть и освобождают.
+500

И архитектура ОС тут не причем! Всё должно одинаково/аналогично работать на разных платформах..
Записан

ArchLinux x86_64 / Win10 64 bit
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #65 : Сентябрь 16, 2009, 14:10 »

Тут идет речь о basic thread-safety. Т.е. безопасных одновременных вызовах const методов. Для list естественно это тоже справедливо, хотя  текущий стандарт языка, частью которого является stl, про потоки ничего не знает.
Я с этим не работал но мне это интересно. Нельзя ли это как-то выделить в новую тему и обсудить более подробно?
Записан
BRE
Гость
« Ответ #66 : Сентябрь 16, 2009, 14:15 »

Цитировать
Обещали по squeeze память освобождать - вот пусть и освобождают.
+500

И архитектура ОС тут не причем! Всё должно одинаково/аналогично работать на разных платформах..
Камрады, squeeze освобождает.
И на всех платформах все работает одинаково.
Что могут сделать Тролли, если для процесса в linux отдается 3 Гб, а в венде 2. Это особенности ОС.

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

Сообщений: 11445


Просмотр профиля
« Ответ #67 : Сентябрь 16, 2009, 16:31 »

Камрады, squeeze освобождает.
И на всех платформах все работает одинаково.
Что могут сделать Тролли, если для процесса в linux отдается 3 Гб, а в венде 2. Это особенности ОС.
Проверяю на в 10 раз меньших блоках

Код:
#define  NUM_TEST	(20 * 1024 * 1024)

int i, j;
QVector<int> theVector[100];

for (i = 0; i < 100; ++i) {
theVector[i].reserve(NUM_TEST);
for (j = 0; j < NUM_TEST; ++j)
theVector[i].push_back(i);
theVector[i].resize(2);
theVector[i].squeeze();
}
Расход памяти непрерывно растет до 3 Gb, затем - вылет
Записан
BRE
Гость
« Ответ #68 : Сентябрь 16, 2009, 19:56 »

Igors, попробуй на Мас такой код:
Код
C++ (Qt)
       QVector<int> v1;
       v1.reserve( 100000 );
       qDebug() << &v1[ 0 ] << &v1[ 99999 ];
       v1.resize(2);                        
       v1.squeeze();                        
 
       QVector<int> v2;
       v2.reserve( 90000 );
       qDebug() << &v2[ 0 ] << &v2[ 89999 ];
 
В linux точно (в венде я думаю тоже), v2 выделяется в адресном пространстве, которое раньше принадлежало v1. Т.е. squeeze нормально отдает память.

Код
C++ (Qt)
       const uint NUM_TEST = 1000 * 1024 * 1024;
 
       QVector<int> theVector;
       int *old_pos = 0;      
 
       for( uint i = 0; i < NUM_TEST; ++i )
       {                                  
               theVector.push_back( i );  
               if( old_pos != &theVector[ 0 ] )
               {                              
                       old_pos = &theVector[ 0 ];
                       qDebug() << hex << qSetFieldWidth( 8 ) << i << &theVector[ 0 ];
               }                                                                      
       }                                                                              
 
А этот код показывает как будет мигрировать непрерывный кусок памяти по адресному пространству, пока не исчерпает его.

Вроде все логично и предсказуемо.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #69 : Сентябрь 16, 2009, 21:29 »

1й код
Код:
ASSERT failure in QVector<T>::operator[]: "index out of range", file /Library/Frameworks/QtCore.framework/Headers/qvector.h, line 337
Abort trap
падает
macbook, 4ГБ ОП на борту
« Последнее редактирование: Сентябрь 16, 2009, 21:32 от Авварон » Записан
BRE
Гость
« Ответ #70 : Сентябрь 16, 2009, 21:37 »

1й код
Код:
ASSERT failure in QVector<T>::operator[]: "index out of range", file /Library/Frameworks/QtCore.framework/Headers/qvector.h, line 337
Abort trap
падает
macbook, 4ГБ ОП на борту

А на каком qDebug падает: первом или втором?
 Шокированный Непонимающий
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #71 : Сентябрь 16, 2009, 21:45 »

вывод приложения я привел) на 1м видимо в v1[ 99999 ]
added: так, стоп, я ушел курить, почему она всегда падает О_о
added2: то ли место не резервируется, то ли я криворук
« Последнее редактирование: Сентябрь 16, 2009, 21:55 от Авварон » Записан
BRE
Гость
« Ответ #72 : Сентябрь 16, 2009, 22:17 »

вывод приложения я привел) на 1м видимо в v1[ 99999 ]
added: так, стоп, я ушел курить, почему она всегда падает О_о
added2: то ли место не резервируется, то ли я криворук
reserve только резервирует место, но не увеличивает размер вектора (v1.size() == 0).
У тебя скорее всего используется debug версия Qt и там отрабатывает Q_ASSERT_X.
Вместо reserve попробуй использовать resize.

Новая версия тестовой программы (показывает точную область с учетом capacity()):
Код
C++ (Qt)
       QVector<int> v1;
       QVector<int> v2;
       const int sizeV1 = 100000;
       const int sizeV2 = 60000;
 
       v1.resize( sizeV1 );
       qDebug() << v1.size() << v1.capacity() << &v1[ 0 ] << &v1[ 0 ] + v1.capacity() * sizeof( int );
       v1.resize( 2 );                                                                
       v1.squeeze();                                                                  
 
       v2.resize( sizeV2 );
       qDebug() << v2.size() << v2.capacity() << &v2[ 0 ] << &v2[ 0 ] + v2.capacity() * sizeof( int );
 
« Последнее редактирование: Сентябрь 17, 2009, 07:18 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #73 : Сентябрь 17, 2009, 11:09 »

Igors, попробуй на Мас такой код:
...
В linux точно (в венде я думаю тоже), v2 выделяется в адресном пространстве, которое раньше принадлежало v1. Т.е. squeeze нормально отдает память.

Вроде все логично и предсказуемо.
На Вашей платформе - да. На моей - нет. Я немного добавил кода чтобы избежать "out of range"

Код:
QVector<int> v1; 
v1.reserve( 100000 );
for (int i = 0; i < 100 * 1000; ++i) v1.push_back(i);
qDebug() << &v1[ 0 ] << &v1[ 99999 ];
v1.resize(2);                       
v1.squeeze();                       

QVector<int> v2;
v2.reserve( 90000 );
for (int i = 0; i < 90 * 1000; ++i) v2.push_back(i);
qDebug() << &v2[ 0 ] << &v2[ 89999 ];

Консоль
Код:
[Session started at 2009-09-17 10:57:06 +0300.]
0x1c010 0x7da8c
0x7e010 0xd5e4c
Записан
BRE
Гость
« Ответ #74 : Сентябрь 17, 2009, 11:15 »

Igors, попробуй последний пример.
Он показывает на сколько элементов реально выделяется буфер и соответственно точное расположение его в памяти. Еще попробуй изменять размер второго вектора и смотреть на реальный размер буфера.
Код
C++ (Qt)
       QVector<int> v1;
       QVector<int> v2;
       const int sizeV1 = 100000;
       const int sizeV2 = 60000;
 
       v1.resize( sizeV1 );
       qDebug() << v1.size() << v1.capacity() << &v1[ 0 ] << &v1[ 0 ] + v1.capacity() * sizeof( int );
       v1.resize( 2 );                                                                
       v1.squeeze();                                                                  
 
       v2.resize( sizeV2 );
       qDebug() << v2.size() << v2.capacity() << &v2[ 0 ] << &v2[ 0 ] + v2.capacity() * sizeof( int );
 
Записан
Страниц: 1 ... 3 4 [5] 6 7   Вверх
  Печать  
 
Перейти в:  


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