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

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

Страниц: 1 2 [3] 4   Вниз
  Печать  
Автор Тема: Qt vs фрагментация памяти  (Прочитано 21845 раз)
BRE
Гость
« Ответ #30 : Март 19, 2010, 14:11 »

Но в целом это не метод.
Я так понял, что речь идет про системный swap?
Ну так никто не обещал, что будет легко.  Подмигивающий
Обещали, что при наличие свободных страниц физической памяти или места в свопе, ядро предоставит процессу физическую память.
Если на машине 4 Gb оперативки, задействовать память свыше этого значения, да еще и чтобы эта память работала также как физическая - вряд ли удастся.  Улыбающийся
Это уже разработчик должен думать, что бы буферы, с которыми ведется интенсивная работа, всегда находились в физической памяти.

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

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Март 19, 2010, 19:01 »

Я так понял, что речь идет про системный swap?
Про оба. Я сам делаю swap на диск больших данных, если не влазит - обрабатывается по частям. Попытки "использовать больше памяти" (спихнуть все заботы со  swap'ом на ОС) ничего хорошего не приносят.
Это уже разработчик должен думать, что бы буферы, с которыми ведется интенсивная работа, всегда находились в физической памяти.
Должен. Но это куда как труднее чем писать красивые дефрагментаторы  Улыбающийся
Записан
BRE
Гость
« Ответ #32 : Март 19, 2010, 19:16 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #33 : Март 19, 2010, 20:35 »

Что трудней, обеспечить что бы размер буфера помещался в физической памяти?
Обеспечить работу в рамках ограниченного объема памяти (часто заданного пользователем)
Записан
ритт
Гость
« Ответ #34 : Март 19, 2010, 20:51 »

а звучит тема, звучит...
> Qt vs фрагментация памяти
как "лего vs равномерное распределение средств в гос.учреждениях" Улыбающийся

упд. поставил строчки ближе во избежание...
« Последнее редактирование: Март 20, 2010, 00:21 от Константин » Записан
niXman
Гость
« Ответ #35 : Март 19, 2010, 21:19 »

Igors, детский сад, иначе не скажешь!
прочитав вашу "идею" с 8мью гигами, остается вспоминать лучшее о вас. ибо то о чем вы написали, это антипаттерн "глоб" или "спагетти".
ребятушки, не хочу показаться хамом/выпендрежником, но вы хоть какое-то понятие о культуре программирования имеете?! ваши мысли, напоминают дитёнка, наконец-то убившего котенка! конечно, он рад, столько нового узнал! и наконец-то у него это получилось! но итог его поступка каков?

вы же взрослые люди, должны понимать "то", о чем говорит Igors.

нехочу никого обидеть, просто люблю идеальный код. не хотите, не соглашайтесь со мной. накласть.
« Последнее редактирование: Март 19, 2010, 21:22 от niXman » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #36 : Март 19, 2010, 22:29 »

Не пойму чего ж я такого страшного сказал?  Улыбающийся Что мне было интересно проверить работу с большой памятью? Так это каждый бы сделал чтобы удовлетворить свое любопытство. И причем здесь гос.учреждения к которым я не имею никакого отношения последние 20 лет  Непонимающий
Записан
Amigo_sa
Гость
« Ответ #37 : Май 04, 2010, 16:53 »

После перерыва решил вернуться к этой теме:)
Решил написать код, который зафрагментирует нафиг всю память, как мне советовали, начал с более простых примеров, обнаружил полное непонимание механизма выделения памяти.

Написал простой код, который создает в куче элемы пока память не закончится, собирал в релизе.
Код:
#include <new>
#include <iostream>

class T
{
int f;
int g;
int k;
};

int main(int argc, char *argv[])
{
std::cout << sizeof(int);
int count = 0;
try
{
forever
{
[b]double* p = new double;[/b]
count++;
if (!(count % 1000000))
{
std::cout << count << "\n";
}
}
}
catch(std::bad_alloc &ba)
{
std::cout << "bad_alloc ";
std::cout << count;
}
catch(...)
{
std::cout << "unknown " << count;
}
}
В выделенной строчке менял тип создаваемых элементов на int и на T (его размер равен 12). Обнаружил что интов создается 133 млн элементов с копейками, то есть полезной памяти чуть больше пол-гига, в диспетчере задач при этом приложение занимает больше 2-х гигов. Менял тип на double и выделяется теже 133 млн элемов! Полезной памяти уже больше гига получается. Я думал, что new дописывает какую то служебную информацию в блок памяти, поэтому сделал свой тип Т, думая, что чем меньше new будет сделано тем больше полезной памяти выделится. Создалось 88 млн элемов - тот же гиг полезной памяти... 133/88 ~= 12/8...
Вот решил обратиться к общественности с просьбой объяснить, почему так происходит. почему интов выделяется так мало и почему процесс может создать всего чуть больше гига полезной памяти.
Спасибо за ответы.

П.С.  Windows Vista, Visual Studio 2008
Записан
BRE
Гость
« Ответ #38 : Май 04, 2010, 19:22 »

Посмотри на этот пример:
Код
C++ (Qt)
#include <new>
#include <iostream>
 
template<typename T>
void func()
{
       std::cout << "size type: " << sizeof( T ) << std::endl;
       T *p1 = new T;
       std::cout << p1 << std::endl;
       T *p2 = new T;
       std::cout << p2 << std::endl;
 
       std::cout << "size block: " << ((char*)p2 - (char*)p1) << std::endl;
}
 
struct Type1
{
       int     a;
       int     b;
       int     c;
       int     d;
       int     e;
};
 
struct Type2
{
       double  a;
       double  b;
       double  c;
       double  d;
       double  e;
};
 
int main( int argc, char *argv[] )
{
       func<int>();
       std::cout << "------" << std::endl;
       func<double>();
       std::cout << "------" << std::endl;
       func<Type1>();
       std::cout << "------" << std::endl;
       func<Type2>();
}
 

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

Сообщений: 11445


Просмотр профиля
« Ответ #39 : Май 04, 2010, 20:01 »

Это личное дело ОС какой "размер параграфа", т.е. до какого значения округлять фактический размер выделяемого блока. Если Вы продолжите эксперименты, напр. с размером структуры 1024 байт (а еще лучше 4096), то, полагаю, "КПД" будет близко к единице  Улыбающийся

Практически всегда накладно делать много распределений маленьких блоков. Такие данные надо распределять chunk'ами (т.е. порциями) так чтобы выделяемый размер был достаточно велик. Эрудиты рекомендуют использовать аллокаторы boost и.т.п. - но это несложно и сделать самому.

Также не следует делать никаких предположений о размере структуры (мол, это 12 байт). Всегда надо использовать sizeof.



 
Записан
Amigo_sa
Гость
« Ответ #40 : Май 05, 2010, 10:05 »

Посмотри на этот пример:
*********
Он показывает какого размера блок реально выделяется при каждом типе.

Да и вправду, для инта и дабла размеры блоков совпали и равны 16 байт, как раз чтобы заполнить 2 гига, доступных приложению нужно 133 млн элемов...

Поигрался дальше со структурками и с выравниванием, получилось следующее:
1. минимальный выделяемый блок = 16 байт.
2. каждая операция new отбирает 8 байт у блока.
3. у меня получалось что если sizeof(T) + 8 байт на new > 32 то данные выделялись на разных страницах, что в общем не снижает эффективности.
4. при увеличении размера структуры, как и говорил Igors, размер полезной памяти увеличивается и приблизижается к 2-м гигам, как и обещал Рихтер:)

BRE, Igors, Спасибо большое за ответы!
Записан
Sancho_s_rancho
Гость
« Ответ #41 : Май 05, 2010, 10:47 »

Не совсем понял о чем вообще тред, похоже на какие-то забавы. Если хотите занимать меньше памяти, то отключите выравнивание. Скорость ниже, плотность больше. См. опции компилятора на тему _unaligned
Записан
Amigo_sa
Гость
« Ответ #42 : Май 05, 2010, 10:51 »

Не совсем понял о чем вообще тред, похоже на какие-то забавы. Если хотите занимать меньше памяти, то отключите выравнивание. Скорость ниже, плотность больше. См. опции компилятора на тему _unaligned
Тред о том, как работает динамическая память. Надеюсь, что кроме меня еще кому нибудь будет полезно.
Записан
Amigo_sa
Гость
« Ответ #43 : Май 05, 2010, 12:06 »

Подолжаю свои игрушки...
Код:
#include <QList>
#include <new>
#include <iostream>

struct Type1
{
        double     a;
        double     b;
        double     c;
        double     d;  
double e;
};
 
struct Type2
{
        double  a;
        double  b;
        double  c;
        double  d;
        double  e;
double f;
};

class T
{
double f;
double g;
double h;
double d;
int k;
};

int main(int argc, char *argv[])
{
//std::cout << sizeof(T);
forever
{
int count = 0;
QList<void*> pointers;
try
{
forever
{
Type1* p1 = new Type1;
Type2* p2 = new Type2;
T* p3 = new T;

delete p1;
delete p3;

pointers.append(p2);

count++;
if (!(count % 1000000))
{
std::cout << count << "\n";
}
}
}
catch(std::bad_alloc &ba)
{
std::cout << "bad_alloc ";
std::cout << count;
std::cout << "\n";
foreach(void* p, pointers)
{
delete p;
}
pointers.clear();
}
catch(...)
{
std::cout << "unknown " << count;
}
}
}
Этот код фрагментирует примерно половину памяти процесса, что уже очень немало.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #44 : Май 05, 2010, 15:37 »

Если хотите занимать меньше памяти, то отключите выравнивание. Скорость ниже, плотность больше. См. опции компилятора на тему _unaligned
Это не поможет при распределении маленьких блоков (как обсуждалось выше.) "Зато" есть отличные шансы посадить скорость, причем это зависит от конкретного процессора.

Подолжаю свои игрушки...
На мой взгляд пользы от таких игрушек куда больше чем от бестолкового заучивания чужих классов  Улыбающийся
Интересно было бы пощупать контейнеры STL на предмет их экономичнрсти по сравнении с простым new/malloc. А то шуму много о "шаблонах проектирования" и.т.п. Ну std::vector все просто а вот напр. std::list, std::set - может и пару других - не лишено интереса.
Записан
Страниц: 1 2 [3] 4   Вверх
  Печать  
 
Перейти в:  


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