Комментарии 3
Да, это перевод статьи https://lo.calho.st/posts/black-magic-buffer/, ссылка на которую приведена в тексте.
У нас немного разные сценарии. Тот мужик записывал в буфер сообщения разной длины и хотел избавиться от проверки, не вылезет ли сообщение за границы буфера. У меня сообщения (матрицы) всегда одинаковой длины. Мне нужно экономить место и операции.
Озвученная проблема:
а) нужно иметь писателя и иметь читателя(лей) для потоковых данных, приближенных к realtime
б) нужно максимально быстро переиспользовать уже прочитанную / обработанную память
в) нужно обеспечить непрерывность в памяти нескольких подряд идущих элементов размером в несколько килобайт или мегабайт
Теперь вопрос - а что мешает просто зарезервировать через mmap() (но не выделить) диапазон адресов размером в несколько терабайт (для современных 64-х битных архитектур с 48 реальными адресуемыми битами верхний предел около 128 терабайт, в реальности чуть менее). Физическая память будет выделяться (commit) при записи. Уже обработанную память - просто освобождать через madvise(MADV_DONTNEED). Быстрее в этом мире ничего нет, т.к. malloc()/free()/new/delete это просто обертки над mmap() с его commit on demand
80TB это примерно 80млн чанков размером по 1MB. А при достижении "верхнего предела" можно просто взять паузу и сделать remap() активной часть буфера в начало.
Не просто так конечно - там уже нужно будет две последовательно очень большие области, скажем по 40TB. И если наш читающий хвост переехал из первой области во вторую (т.е. первая стала полностью не нужна), то мы быстро первую отмпаливаем целиком, вторую ставим на место первой через mremap(), и еще раз делаем заново mmap() второй области с MAP_FIXED.
Linux довольно консервативен в части использования диапазонов адресов - все что не первый и не последний терабайт из адресуемых 128TB userspace - это система практически не задействует сама (heap растет снизу вверх, стек и mmap()ы без указания адреса - сверху вниз).

Чёрная магия C++: Быстрый кольцевой буфер