All streams
Search
Write a publication
Pull to refresh
103
0.2

User

Send message
Спасибо огромное. Набросал тестик — работает.
Как я его раньше не видел — ума не приложу
Если бы я начал описывать, как построить связный список или зачем нужно выравнивание, то читатели, до которых я хотел донести информацию, плюнули бы на середине и закрыли страницу.

Статья расчитана на тех, кто уже пытался писать свои аллокаторы. Акцент в статье — на перегрузке операторов и синтаксических конструкциях для работы со своими аллокаторами, как с минимальными затратами преобразовать существующую программу.

Тривиальные классы я сначала не хотел приводить, затем засунул под спойлер.

вы правы, сейчас убедился, что на Core2 порядок обхода не важен.
очень давно тестил на Celeron D 320, были другие результаты.
1. Удаление оптимизатором пустого цикла не происходит, тогда время было бы 0. Тем более, в отдельных случаях я достиг времени, как у CLR, так что сравнение честное.

2. Как раз первый пример и устраняет фрагментацию. Объекты разных типов лежат в непересекающихся пулах, а внутри пула фрагментация значения не имеет. Поиск свободного блока — O(1), все блоки в пуле одинаковые, поэтому нет случая, когда много свободного места по мелочи, а взять нечего.

3. Первый пример предусматривает возврат неиспользуемой памяти, смотрите внимательнее. Если алгоритм съест всю память, то значит она вся нужна (выделена)

4. Ну отлично. Проверьте всё же класс BlockAlloc, ведь переделки программы совсем тривиальные (и ещё вернуть надо в состояние до-GC, когда delete не забывали вызывать)
100к записей гридам — проблема явно. пользователь не робот, зачем ему столько
Эх, FastMM… Юзал в дельфи для поиска утечек памяти. Очень удобно — при закрытии приложения каждая утечка описана со stacktrace-ом, где сделано выделение.

В MSVC всё печальнее — только список утечек, без стека, если включать _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF)

Может, кто посоветует leak detectors для MSVC.
Маленькие объекты должны быть struct, а не class.
Создать массив достаточной длины из struct, и везде ссылаться на объекты не по ссылке, а по индексу в массиве.
этим открытый код и прекрасен. мелкие наработки аккумулируются
Да, этот класс я видел, когда готовил статью ))
Впрочем, переправил везде. Ведь кто-то может научиться кривой терминологии.
Изобретение велосипеда всегда интересно :)
Ваш подход описан в первой части. Честно говоря, в рабочей версии управление большими страницами я тоже сделал связным списком (данные на следующую страницу — в хидере страницы). Но, чтобы не перегружать статью, переписал на vector<>, на быстродействие это окажет минимальное влияние.

В статье описаны две совершенно разных подхода:
1. Блоки одинакового размера, с активным выделением-освобождением
2. Разношёрстные блоки с быстрым выделением, но освобождаются только все сразу (должны иметь одинаковое время жизни смерти)
Да, во втором случае, в пуле могуть быть разные объекты, но т.к. удаление запрещено, выделение памяти очень простое и разделение по пулам мне кажется, не даст ускорения (с чего бы...)
hole punching не поюзаешь для коммерческих решений. это же эксплуатация дыры, по сути.
проверял, оно работает далеко не везде: на ADSL-модеме ZyXEL работало, а на роутерах с RouterOS или FreeBSD (NAT силами ipfw) — увы. то есть, надёжный способ — релеи

кроме того, для координации hole punching нужен сторонний сервер, а он уже может ответить, что фокус не удался и трафик надо гнать через релей, даже когда роутеры клиентов позволили бы прямое соединение
судя по примерам, автор говорит о программах, меняющих свою логику под воздействием входных данных.

на любой интерпретатор можно посмотреть в двух точек зрения:
— он выполняет поступающие команды строго по порядку и ничего неожиданного в нём нет.
— при поступлении программы он начинает работать по логике программы, совершенно непредсказуемо на момент создания интерпретатора

кто переводит с русского на английский — интерпретатор или подаваемая на него программа? а если провести грань между ними сложно, как в вышеприведённой программе STUDENT?

парадокс описан ещё Джоном Сёрлем
разочарован. статья озаглавлена «как работает архитектура». ожидал, что раскроют технические подробности, а вместо этого — маркетинговая лапша на уши.
я люблю assertions и пишу их часто.
наверное, я дурак ))
да, и ещё проблема этого кода — создание CValue вне наследника CStructBase. тогда этот CValue допишется в последний созданный экземпляр CStructBase (который может быть уже разрушен).

по-хорошему, после завершения всех конструкторов членов CMyStruct надо сделать g_mapByThreadId[GetCurrentThreadId()] = NULL

что-то не соображу, как это сделать автоматически, чтобы не повторять в каждом конструкторе CMyStruct
не нужно городить с блокировками и мапой, когда в ОС есть поддержка thread-переменных на уровне ОС без блокировок и с минимальным оверхедом

в с++
__declspec(thread) CStructBase* currentClass;

в C#, Pascal и т.п. тоже есть аналогичные windows-specific кейворды ([ThreadStatic], threadvar)

Information

Rating
2,478-th
Location
Россия
Registered
Activity