Войти
ПроектыФорумУтилиты

Движок 'Сухарь Ванильный' (57 стр)

Страницы: 156 57 58 5962 Следующая »
#840
16:45, 27 дек. 2012
// in: xpos,ypos - window upper left corner position
// in: nowx,nowy - window client area size
//
LONG styleW=WS_BORDER | WS_CAPTION | WS_OVERLAPPED | WS_TILED;
RECT clien_rect;
//
clien_rect.left=xpos;
clien_rect.top=ypos;
clien_rect.right=nowx + xpos; // !!!
clien_rect.bottom=nowy + ypos; // !!!
AdjustWindowRect(&clien_rect,styleW,FALSE);
//          < adjust window client rectangle
//          > create window
hWnd = CreateWindowEx( 0, ENAME, ENAME, styleW,
           (int )clien_rect.left,
           (int )clien_rect.top,
           (int )(clien_rect.right - clien_rect.left), // !!!
           (int )(clien_rect.bottom - clien_rect.top), // !!!
       NULL , NULL, wc.hInstance, NULL);
//          < create window

Правил в браузере, мог очепятаться


#841
19:27, 27 дек. 2012

Всё, я уже проверил, везде работает.

Собственно, ошибка была довольно глупая. Ну надо же было авторам структуры RECT назвать поля left и right. А при позиционировании окна используются эти поля как startX и sizeX. Понятно, что из за этих названий и путаница.

MATov
Всё, спасибо. Теперь точно работает. <:]

#842
19:31, 27 дек. 2012

sb3d
> Ну надо же было авторам структуры RECT назвать поля left и right
Это ж винапи, писалось индусами для индусов:)

Это вам не юниксовые апи с невзрачными параметрами x, y, w, h

#843
20:22, 27 дек. 2012

sb3d
> А при позиционировании окна используются эти поля как startX и sizeX. Понятно,
> что из за этих названий и путаница.
ну просто CreateWindow и не RECT совсем принимает, и аргументы там названы нормально, а именно: x, y, width, height, просто внимательней надо быть и всё будет хорошо :)

#844
7:48, 28 дек. 2012

А вот такой общий вопрос: частое выделение и освобождение памяти, это нормальная практика?

Выделяю я память через operator new, освобождаю через operator delete.
Вот если за один кадр программы таких выделений и освобождений десятки и сотни, это нормально? Нет каких нибудь подводных камней при таком использовании?

#845
7:53, 28 дек. 2012

Это нормально в ОСях с адекватным менеджером памяти. Но если у вас память выделяется каждый кадр - я бы повнимательнее присмотрелся к архитектуре.

#846
7:56, 28 дек. 2012

Может быть, тогда проще написать свой менеджер памяти? Который бы в начале работы выделял кусок с запасом, а всем микро-запросам уже из этого большого куска давал бы участки?
Вообще, есть такая практика? Пишут свой простой менеджер памяти?

#847
8:03, 28 дек. 2012

Проще написать свою ОС. Но действительно, если сильно хочется, можно сделать небольшой менеджер объектов, который экстентами выделяет память. Но делать такой менеджер нужно только если у вас постоянно создаётся и удаляется куча объектов одинакового размера (стратежка и юниты), иначе нет особого смысла. До тех пока выделение памяти не тормозит я думают не стоит заморачиваться:)

#848
8:17, 28 дек. 2012

sb3d
> Вот если за один кадр программы таких выделений и освобождений десятки и сотни, это нормально?
А для каких объектов такое может понадобиться?

#849
8:37, 28 дек. 2012

[A][R][T]
> А для каких объектов такое может понадобиться?
Выделение временных буферов для самых разных целей. Некоторые операции требуют временных буферов. Можно, конечно, все буферы выделить сразу при старте движка, но, по моему, это просто некрасиво: буфер создаётся в одном месте, а используется в другом.

RPG
> Проще написать свою ОС.
Конечно же, я говорю об обёртке над стандартным выделением\освобождением памяти средствами языка.

> Но действительно, если сильно хочется, можно сделать
> небольшой менеджер объектов, который экстентами выделяет память.
Я ещё вот что хочу проверить: не улучшит ли это быстродействие? Просто из за лучшего попадание в кэш процессора за счёт снижения нагрузки на ассоциативность его кэша. Такой опыт у меня уже был: я выделил палитру и спрайт в разных блоках памяти, и сравнил скорость работы при выделении места для палитры и спрайта в одной области. Победил второй способ. То есть кэшируются лучше те данные, которые лежат в одной выделенной области.

В общем, скорее всего напишу обёртку и посмотрю.

#850
8:09, 29 дек. 2012

Коротенечко отчёт. О том, как пытался сделать свою обёртку над указателями и выделением памяти.

Во первых, сделал. Сделал такую систему: В начале создаётся одна 'большая' область памяти. Назовём её ангар. Далее, когда пользователь запрашивает блок памяти, то этот участок выделяется ему в этом ангаре. Когда же пользователь хочет освободить кусок памяти, то система сдвигает все оставшиеся данные так, чтобы они лежали плотно, без пробелов между ними. В одном 'большом' ангаре.

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

Далее, вторым неприятным сюрпризом было то, что многие указатели пользователя - локальны в пределах одной функции. Выделив память под этот указатель, пользователь потом копировал его в глобальный указатель, выходил из функции, и его локальный указатель переставал существовать. А в предыдущем пункте я сказал, что нужно было хранить указатели на указатели. Которые становились невалидны после такого финта.

Ну, так или иначе, но все эти вопросы я решил, справился, и заставил стресс тесты работать без сбоев.

Теперь результат этой обёртки над выделением памяти.
1. Оказывается, выравнивание ускоряет в 2.5 раза работу с памятью! :) Лол, это удивило. Пришлось всё выравнивать вручную.
2. Ускорения, но и замедления - никакого не обнаружилось. Тут подробнее. Я ожидал, что если, к примеру, у нас есть 15 спрайтов. Если вместо того, чтобы каждый спрайт лежал в своей области памяти, менеджер памяти будет класть их рядом, да ещё и сдвигать вместе, то я ожидал прироста быстродействия от лучшего попадания в кэш. Этого не произошло.

Итого, с интересом день повозился, попутно исправил пару багов в движке, и отказался от своей обёртки над памятью и указателями. :)

#851
8:23, 29 дек. 2012

sb3d
> Во первых, сделал. Сделал такую систему: В начале создаётся одна 'большая'
> область памяти. Назовём её ангар. Далее, когда пользователь запрашивает блок
> памяти, то этот участок выделяется ему в этом ангаре. Когда же пользователь
> хочет освободить кусок памяти, то система сдвигает все оставшиеся данные так,
> чтобы они лежали плотно, без пробелов между ними. В одном 'большом' ангаре.
Погуглите SLAB allocator, гораздо более эффективный метод распределения кусков памяти.
sb3d
> Первым неприятным сюрпризом было то, что, оказывается, нужно хранить все
> указатели на указатели пользователя. Для того, чтобы сдвигать его данные
> незаметно для него. Ведь при сдвиге самого участка памяти - необходимо сдвинуть
> и пользовательский указатель на этот участок.
ОС так и делает, просто память выделяет страницами, чтобы не плодить указатели и хранит указатели не на пользовательские указатели а на области памяти. Я же говорил что проще ОС написать)

Вы пытались за день сделать то что Microsoft уже 20 лет сделать не может - написать нормальный менеджер памяти для общего случая - случайные куски переменной длины выделяются и освобождаются. Надо было писать менеджер для частных случаев, когда вы пишете менеджер, заранее зная, какие данные там будут храниться, тогда возможно ускорение. Свой менеджер памяти, довольно быстрый, вы найдёте в игровом движке CUBE, я не говорю передирать, но хоть представление иметь будете, что это такое.

#852
9:47, 29 дек. 2012

sb3d
> Ну, так или иначе, но все эти вопросы я решил

Встречный вопрос - а как? =) Я когда пописывал скриптовый язык - была в сущности та же самая задача - значения переменных скрипта хранились в куче "с уплотнением", но ссылки на эти переменные были как в разных "областях видимости" (тоже контейнеры) скриптодвигла, так и могли копироваться через параметры и возвращаемые значения в С++ коде и пришлось забарывать в сущности ту же проблему. В итоге у меня получилась переменная-обёртка над ссылкой размером 3 указателя, но в С++ коде она совершенно прозрачно существовала как POD-like типа - копируй и передавай куда хочешь и как хочешь в рамках стандартной семантики. При этом во всех местах где не велась работа сразу со множествами ссылок была константность времени работы всех копирований и так далее. Да и собственно работа с множеством ссылок требовала ровно столько операций сколько этих ссылок есть, не больше. Хотелось бы сравнить подходы. =)

#853
9:49, 29 дек. 2012

sb3d
> 2. Ускорения, но и замедления - никакого не обнаружилось. Тут подробнее. Я
> ожидал, что если, к примеру, у нас есть 15 спрайтов. Если вместо того, чтобы
> каждый спрайт лежал в своей области памяти, менеджер памяти будет класть их
> рядом, да ещё и сдвигать вместе, то я ожидал прироста быстродействия от лучшего
> попадания в кэш. Этого не произошло.

Так для того чтобы обычная куча зафелила плотность упаковки с ней надо активно поработать - удалять - вставлять другого размера - снова удалять и так далее. А так то обычная куча тоже положит всё рядом и плотненько, если спрайты допустим инициализировались в одном месте и между ними не было активной и грузной работы с кучей.

#854
9:53, 29 дек. 2012

sb3d
> вторым неприятным сюрпризом было то, что многие указатели пользователя -
> локальны в пределах одной функции. Выделив память под этот указатель,
> пользователь потом копировал его в глобальный указатель, выходил из функции, и
> его локальный указатель переставал существовать.
Сказал "А" - говори "Б". Сделал такой менеджер - пиши сборщик мусора.
В некоторых случаях не сильно большие куски памяти для локальных нужд процедуры можно выделять на стэке, смотри, к примеру, код моей процедуры RESIZE().

Страницы: 156 57 58 5962 Следующая »
ПроектыФорумУтилиты

Тема в архиве.