Hacker News Digest

Тег: #memory-management

Постов: 6

We rewrote the Ghostty GTK application (mitchellh.com) 🔥 Горячее 💬 Длинная дискуссия

Ghostty GTK-часть переписана с нуля
Проект завершён: Linux/BSD-версия теперь полностью использует GObject из Zig и проверена Valgrind.

Что изменилось

  • Zig-структуры обёрнуты в GObject; память управляется счётчиками ссылок.
  • При обновлении конфига старый объект освобождается автоматически, когда исчезают ссылки.
  • Появились сигналы, свойства, действия GTK и современные UI-файлы Blueprint.
  • Новые виджеты добавляются быстрее (анимированная рамка, вкладки в заголовке и т.д.).

Valgrind Каждый коммит прогонялся под Valgrind.

  • Потребовался большой suppression-файл (в основном GTK/драйверы).
  • Найдены: утечка и неопределённое обращение в Zig-коде, ошибка WeakRef в GTK, которые иначе вызывали редкие краши.

by tosh • 14 августа 2025 г. в 21:19 • 410 points

ОригиналHN

#zig#gtk#gobject#valgrind#linux#bsd#memory-management

Комментарии (194)

  • Ghostty переписывает GUI на GTK/Zig, столкнувшись с проблемами GObject и управления памятью.
  • Участники обсуждают, что GTK навязывает свою ООП-модель и счётчики ссылок, что сложно сочетать с Zig/Rust.
  • Некоторые считают GTK не «родной» на Linux и предлагают Vala, Qt или собственный UI.
  • Пользователи жалуются на баги прокрутки, копирования, nano и отсутствие поиска.
  • Автор признаёт выбор GTK компромиссом ради кроссплатформенности и «родного» вида.

Going faster than memcpy (squadrick.dev)

Как обогнать memcpy

Профилируя Shadesmar, увидел: при больших (>512 КБ) сообщениях 97 % времени уходит на memcpy между процессной и разделяемой памятью. Решил ускорить копирование.


Разбор memcpy

perf показал:
__memmove_avx_unaligned_erms — это memcpy через memmove, AVX, 32 байта за раз, поддержка не выровненных блоков и ERMS (железный цикл REP MOVSB).

  • memmove выбран, т.к. допускает перекрытие.
  • Для <4 КБ используется SSE2, иначе — REP MOVSB + AVX.
  • Не-временные (NT) инструкции и prefetcht0 уменьшают кэш-промахи.

Способ 1: простой REP MOVSB

void _rep_movsb(void *d, const void *s, size_t n) {
  asm volatile("rep movsb"
               : "=D"(d), "=S"(s), "=c"(n)
               : "0"(d), "1"(s), "2"(n)
               : "memory");
}

Тот же цикл, что и в glibc, но без лишней логики.

by snihalani • 11 августа 2025 г. в 04:59 • 125 points

ОригиналHN

#c#assembly#performance-optimization#memory-management#avx#sse2#inter-process-communication#zero-copy

Комментарии (63)

  • Часть выгоды даёт отказ от лишнего копирования: часто данные можно использовать на месте.
  • Несколько участников отмечают, что без контроля кэшей и правильной сериализации бенчмарки теряют смысл.
  • График в конце вызывает сомнения: скачки пропускной способности выглядят неправдоподобно.
  • Для IPC обсуждают zero-copy через размещение данных сразу в shared memory (Iceoryx, Boost.Interprocess, DPDK).
  • Большинство сходится к выводу: для обычных задач лучше довериться стандартному memcpy/std::memcpy, особенно в glibc.

A fast, growable array with stable pointers in C (danielchasehooper.com)

Моя предыдущая статья о обобщённых структурах данных в C готовила почву к теме: структура, которая заменяет динамические массивы, даёт стабильные указатели и хорошо работает с аренными аллокаторами. Её переоткрывали много раз под разными именами: “levelwise-allocated pile” (2001), в Zig — Segmented List, частично похожая на C++ std::deque. Мне нравится название Per Vognsen — Segment Array.

Скачать мой однофайловый заголовок segment_array.h можно, подписавшись на рассылку.

Идея проста: фиксированный массив указателей на сегменты; каждый следующий сегмент вдвое больше предыдущего; новые сегменты выделяются по мере необходимости. Поскольку элементы не двигаются, указатели на них стабильны, не остаются “дыры” в арене, а доступ по индексу — за O(1).

Реализация

Структура на C:

typedef struct { u32 count; int used_segments; u8 *segments[26]; } SegmentArrayInternal;

Почему всего 26 сегментов? Из 64 бит указателя обычно реально используются 48, так что 49 сегментов уже перекрывают адресное пространство (~256 ТиБ). Я предпочитаю индекс u32 (до ~4 млрд элементов) — это даёт 32 сегмента. Ещё убираем 6 маленьких (1..32), начинаем с 64, остаётся 26 сегментов — хватает для 4 294 967 232 элементов (чуть меньше UINT32_MAX). Фиксированный массив рядом со структурой снижает риск промаха кэша.

Размеры сегментов — степени двойки: проще математика и быстрые сдвиги для индексов.

#define SMALL_SEGMENTS_TO_SKIP 6

#define log2i(X) ((u32) (8*sizeof(unsigned long long)
- __builtin_clzll((X)) - 1))

u32 capacity_for_segment_count(int segment_count) { return ((1 << SMALL_SEGMENTS_TO_SKIP) << segment_count) - (1 << SMALL_SEGMENTS_TO_SKIP); }

void *_sa_get(SegmentArrayInternal sa, u32 index, size_t item_size) { int segment = log2i((index >> SMALL_SEGMENTS_TO_SKIP) + 1); u32 slot = index - capacity_for_segment_count(segment); return sa->segments[segment] + item_sizeslot; }

log2i использует __builtin_clzll (подсчёт ведущих нулей) для быстрого вычисления номера сегмента.

Clang оптимизирует _sa_get до ~10 инструкций x86-64 (-O3), так что узким местом будет память, а не вычисления индекса. При последовательной итерации можно обходить сегменты напрямую; в segment_array.h есть макрос.

Выделение нового элемента:

u32 slots_in_segment(int segment_index) { return (1 << SMALL_SEGMENTS_TO_SKIP) << segment_index; }

void *_sa_alloc(SegmentArrayInternal *sa, size_t item_size) { if (sa->count >= capacity_for_segment_count(sa->used_segments)) { size_t segment_size = item_size * slots_in_segment(sa->used_segments); sa->segments[sa->used_segments++] = malloc(segment_size); } sa->count++; return _sa_get(sa, sa->count-1, item_size); }

Замечание: можно сделать ёмкость строго степенью двойки, если первые два сегмента одинакового размера. Код станет менее изящным, но это спасает от ~50% потерь памяти при использовании как массива бакетов в хеш-таблице со степенью двойки.

Дженерики

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

#define SegmentArray(type)
union {
SegmentArrayInternal internal;
type *payload;
}

Дальше макросы используют payload, чтобы передавать сведения о типе…

by ibobev • 06 августа 2025 г. в 18:21 • 204 points

ОригиналHN

#c#zig#c++#rust#data-structures#memory-management

Комментарии (77)

  • Обсуждается структура «сегментированный массив» (экспоненциальные сегменты), её плюсы и минусы, и сравнение с существующими решениями: std::deque, ropes, Zig std.SegmentedList, rust-array-stump, plf::colony.
  • Критика терминологии: это не «массив» в классическом смысле из‑за неконтигуозной памяти; многие API ожидают сплошной/страйдовый буфер и не подойдут.
  • Производительность: при локальных L1-итерациях вычислительная часть индексации может быть ощутима; для больших объёмов память становится бутылочным горлышком. Предлагаются оптимизации итерации по сегментам и замечания про clz/bsr/lzcnt и опции компилятора.
  • Виртуальная память как альтернатива: резервирование большого диапазона и по мере роста коммит страниц/guard pages; отмечены плюсы на Linux (MAP_POPULATE, mremap), но плохо для embedded/WASM.
  • Сравнение с deque: фиксированные блоки vs экспоненциальные, поддержка prepend, рандом-доступ есть; реализация MSVC критикуется за малый размер блока, GNU/libc++ лучше.
  • Недостатки сегментов: ухудшение предвыборки/кэш-локальности при линейной итерации, отсутствие стабильной непрерывности для API, сложность с хеш-таблицами при росте (rehash), потенциальный перерасход памяти при экспоненциальных размерах.
  • Предложения: настраиваемый минимальный размер сегмента, функции «склейки» мелких сегментов, разбор условий, когда экспоненциальные сегменты оправданы, и замечания о чрезмерной макротрюковости в C/C23.

Multics (multicians.org)

  • Логотип Multics

  • Домой

    • История »
      • Возможности
      • Мифы
      • Project MAC
      • Даты
      • Глоссарий
      • Проект истории
      • Последний сайт
    • Люди »
      • Истории
      • Фотографии
      • Юмор
      • Памятные вещи
    • Библиотека »
      • Статьи и доклады
      • Технические статьи
      • Документы разработки
      • Исходники
      • Симулятор
    • Сайты »
      • Хронология площадок
      • AFDSC (Пентагон, Вашингтон)
      • ASEA (Вестерос, Швеция)
      • Avon (Бристоль, Англия)
      • Bell Canada (2 площадки)
      • CISL (Кембридж, Массачусетс)
      • CNO (Миннеаполис, Миннесота)
      • DND-H (Галифакс, Канада)
      • DOCKMASTER (АНБ, Мэриленд)
      • FORD (Детройт, Мичиган)
      • GM (Детройт, Мичиган)
      • Майнц (Германия)
      • MIT (Кембридж, Массачусетс)
      • NWGS (ВМС США, 4 площадки)
      • OU (Рочестер, Мичиган)
      • PRHA (Сан-Хуан, Пуэрто-Рико)
      • RADC (Рим, Нью-Йорк)
      • RAE (Фарнборо, Англия)
      • STC (Лондон, Англия)
      • System-M (Финикс, Аризона)
      • Systeme X (Лувесьен, Франция)
      • UC/ACTC (Калгари, Канада)
      • USGS (3 площадки)
      • USL (Лафайет, Луизиана)
      • VPI (Блэксберг, Вирджиния)
    • О сайте »
      • Изменения
      • Новости
      • Ссылки
      • Галерея
      • Карта сайта
  • Поиск

  • Меню: История: Возможности | Мифы | Project MAC | Даты

by unleaded • 06 августа 2025 г. в 16:57 • 125 points

ОригиналHN

#multics#unix#security#memory-management#access-control

Комментарии (29)

  • Участники обсуждают влияние Multics на современную вычислительную технику: от безопасности и архитектуры до наследия в текущих проектах (например, STOP, происходящий от SCOMP/STOP).
  • Делятся воспоминаниями об использовании Multics в британских университетах в 80-х: система считалась быстрой, апгрейды памяти были ощутимыми, доступ через терминалы и JANET, позитивный опыт работы.
  • Мнения расходятся: одни критикуют «всеобъемлющесть» дизайна и сложность (в контраст к UNIX), другие подчёркивают сильные стороны Multics — кольца защиты, строгие политики доступа (MAC/ACL), сегментную память и отсутствие переполнений буфера.
  • Отмечают ограниченную портируемость Multics к немногим мэйнфреймам, несмотря на теоретическую переносимость.
  • Ссылаются на полезные ресурсы: мифы о Multics, оценка безопасности B2, страницы по безопасности данных (AIM/MAC), «Три вопроса» для анализа багов, меморабилии, хронологии и список недавних изменений.
  • Обсуждают спад активности оригинальных установок (последние закрытия около 2000 г.), эмулятор DPS8M и печальные новости об уходе участников проекта.
  • Несколько комментаторов переосмыслили роль UNIX после знакомства с историей Multics и более ранними идеями (Xerox PARC), видя в Multics самостоятельную и богатую идеями систему, а не только «предтечу UNIX».

Python performance myths and fairy tales (lwn.net) 💬 Длинная дискуссия

Добро пожаловать на LWN.net

Этот материал для подписчиков стал доступен благодаря читателю LWN. Тысячи подписчиков зависят от LWN как от источника новостей о Linux и свободном ПО. Если статья вам понравилась, пожалуйста, рассмотрите возможность оформления подписки. Спасибо за визит!

Антонио Куни, давний инженер по производительности Python и разработчик PyPy, на EuroPython 2025 в Праге представил доклад «Мифы и сказки про производительность Python». По его мнению, привычная «мудрость» о скорости Python часто вводит в заблуждение. На примерах он показал реальные узкие места и пришел к выводу: в конечном счете предел оптимизаций упирается в управление памятью. Он начал ранний проект SPy, который, возможно, приведет к сверхбыстрому Python.

Он попросил зал поднять руки, кто считает «Python медленным или недостаточно быстрым» — рук было много (в отличие от PyCon Italy). Годы работы с производительностью и общение с разработчиками породили набор мифов, которые он хочет развеять.

Мифы

Миф: «Python не медленный». Да, часто «достаточно быстрый», особенно как «склеечный» язык в эпоху «важен только GPU». Но это верно лишь для части задач. Есть множество программ, где скорость Python критична — отсюда постоянные усилия по оптимизации интерпретатора и перенос горячих участков в Cython, Numba и т.п.

В слайдах он показал множества: «программы, где Python достаточно быстр» — подмножество «всех Python-программ», а снаружи — «все возможные программы». В идеале Python должен подходить для всех; пока что задачи, требующие максимума от процессора, не могут быть на Python. Он хочет расширять «внутренние круги».

Королларий «это всего лишь клей»: «просто перепишите горячее в C/C++» (сегодня — в Rust). Прием рабочий, но быстро упирается в стену: принцип Парето подсказывает оптимизировать 20% кода, где 80% времени, но затем срабатывает закон Амдаля — ускорив горячую часть, вы упираетесь в остальной код, который начинает доминировать во времени выполнения.

Еще миф: «Python медленный, потому что интерпретируемый». Интерпретация — лишь малая часть. Даже выражение p.x * 2 в C/C++/Rust — это загрузка, умножение, сохранение. В Python же нужно определить тип p, вызвать getattribute(), распаковать p.x и 2, выполнить операцию с учетом перегрузок и протоколов, упаковать результат, выделить память и т.д. Это диктуют семантика и динамичность языка, не способ исполнения.

Статические типы

С распространением тайпингов слышно: «теперь компиляторы могут пропускать лишнее и считать напрямую». Пример:

def add(x: int, y: int) -> int:
    return x + y

print(add(2, 3))

Но аннотации не применяются во время выполнения, и можно вызвать:

print(add('hello ', 'world'))  # type: ignore

Чекер доволен, но семантика сложения уже другая. Аннотации бесполезны для оптимизации и скорости, если их не гарантирует рантайм. Более того, в Python легально перегружать операции, меняя поведение в рантайме, что разрушает предпосылки для агрессивных оптимизаций.

by todsacerdoti • 06 августа 2025 г. в 08:36 • 228 points

ОригиналHN

#python#pypy#jit#performance#memory-management#numba#pythran#mypyc#rust#c

Комментарии (200)

  • Обсуждение сосредоточено на мифах о скорости Python: динамичность языка, непредсказуемость типов и плохая кэш-локальность мешают компиляторам и JIT достигать производительности системных языков без компромиссов по совместимости и простоте.
  • Многие отмечают, что JIT и спекулятивное выполнение помогают на «хэппи-пате», но становятся хрупкими: небольшие изменения кода могут срывать оптимизации и резко просаживать скорость.
  • Популярные пути ускорения — PyPy, Numba, Pythran, mypyc, а также перенос «горячих» участков в C/C++/Rust или использование DSL/субсетов (SPy); однако граница вызовов и динамика Python часто «съедают» выгоды.
  • Отмечают альтернативы и эволюцию: Mojo как супермножество Python с статикой и компиляцией, возможное сосуществование компиляторов рядом с CPython вместо «Python 4».
  • Критики указывают, что популярность Python не доказывает его производительность; многие реальные «тормоза» — это не CPU, а I/O и сеть, где помогают async и масштабирование.
  • Скептики считают, что «быстрым» Python не станет без отказа от ключевых динамических свойств (примерно как в JS — оптимизации на общий случай, но с ограничениями); часть участников предлагает оставлять Python для скриптинга и клеевого кода.
  • Вопросы многопоточности, старта интерпретатора и GIL остаются проблемными; параллельно обсуждают идеи «final»-квалификаторов, иммутабельности и GPU/параллельных подходов, но признают их практические ограничения.

A deep dive into Rust and C memory interoperability (notashes.me)

by hyperbrainer • 04 августа 2025 г. в 15:12 • 152 points

ОригиналHN

#rust#c#memory-management

Комментарии (78)

The reason you are not seeing crashes when allocating with Rust and freeing with C (or vice versa) is that by default Rust also uses the libc allocator.https://stdrs.dev/nightly/x86_64-unknown-linux-gnu/src/std/s... Lots of detail, little substance, and misleading section headers