ПО, ЭВМ и АСУ из Таможенного Союза

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » управление памятью » Разновидности буферов


Разновидности буферов

Сообщений 1 страница 3 из 3

1

https://en.wikipedia.org/wiki/Circular_buffer

Есть две разновидности кольцевого буфера (ring-buffer):
- с четырьмя указателями, считается заполненным, когда указатель на конец данных на единицу меньше указателя начала данных (один элемент буфера недоиспользуется)
- с количеством считанных элементов вместо указателя на конец данных (пустой когда там ноль, полный, когда там размер буфера)

Ещё бывает двойной буфер, он позволяет вызывать системную функцию заполнения буфера, которая не знает о том, что буфер циклический и не делает сама перехода через край (Bip Buffer, bipartite buffer) -
[html]<a href="https://www.codeproject.com/Articles/3479/The-Bip-Buffer-The-Circular-Buffer-with-a-Twist">https://www.codeproject.com/Articles/3479/The-Bip-Buffer-The-Circular-Buffer-with-a-Twist</a>[/html]

Упрощённый двойной буфер (ping-pong buffer) - когда есть ровно два элемента, которые используются по очереди, если нужно читать скажем по 4096 байт, то в таком буфере будет восемь килобайт, чтобы читать всегда в одну из половин.

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

Павиа, наверное, использует буфер, реализованный разработчиками рантайма паскаля и не стоял перед выбором его алгоритма работы. С другой стороны, у него есть свой собственный рантайм, как он подошел к решению там?
Ведь в принципе это интересно - разобраться какой алгоритм выбрали разработчики рантайма.

[html]<a href="http://www.pixelbeat.org/programming/stdio_buffering/">http://www.pixelbeat.org/programming/stdio_buffering/</a>[/html]
"The linux pipe buffers have changed to circular buffers (16 x 4KiB)"

Default Buffering modes:
    stdin is buffered (line buffering doesn't affect stdin)
    stdout is buffered (line buffered if connected to a terminal)
    stderr is unbuffered

[html]<a href="https://stackoverflow.com/questions/23472750/how-glibc-manages-buffers">https://stackoverflow.com/questions/23472750/how-glibc-manages-buffers</a>[/html]

[html]<a href="https://www.gnu.org/software/libc/manual/html_node/Stream-Buffering.html">https://www.gnu.org/software/libc/manual/html_node/Stream-Buffering.html</a>
<br />
<a href="https://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html">https://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html</a><br />
<a href="https://www.gnu.org/software/libc/manual/html_node/Controlling-Buffering.html">https://www.gnu.org/software/libc/manual/html_node/Controlling-Buffering.html</a>[/html]

size_t __fbufsize (FILE *stream)
  return the size of the buffer in the stream "stream".
size_t __fpending (FILE *stream)
  returns the number of bytes currently in the output buffer. Function should not be used on buffers in read mode or opened read-only.

[html]<a href="http://kirste.userpage.fu-berlin.de/chemnet/use/info/libc/libc_7.html">http://kirste.userpage.fu-berlin.de/chemnet/use/info/libc/libc_7.html</a>[/html]
ungetc - нет функции для "расчитывания" нескольких символов/байт

https://en.wikipedia.org/wiki/C_file_input/output
Стандартная библиотека копирует данные из входного буфера в буфер пользователя:
int len = fread(&buffer,sizeof(buffer),1,stdin);
Это копирование - лишнее (ядро итак копирует само, когда выполняется системный вызов (syscall) read) и лишнее копирование должно теоретически снижать эффективность. А делается оно всего лишь для того, чтобы скрыть границу кольцевого буфера.

Итак, обязательно ли использовать mmap для обеспечения возможности обобщённого подхода в парсере, или для начала хватит ping-pong-буфера. Что скажет общественность?

Отредактировано Лис (2019-03-26 15:49:37)

0

2

[html]
Посмотрел на код рантайма Павиа.
<br />
<a href="https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L180">https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L180</a>
<br />
Не вдохновился его подходом:
<br />
двигает байты в буфере
<br />
<a href="https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L344-375">https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L344-375</a>
<br />
<a href="https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L867">https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L867</a>
<br />
<a href="https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L231">https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L231</a>
<br />
<a href="https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L1200">https://gitlab.com/pavia00/pop/blob/master/lib/system.pop#L1200</a>
[/html]

Отредактировано Лис (2019-03-26 16:04:19)

0

3

У меня указатель бегает
https://gitlab.com/pavia00/pop/blob/mas … m.pop#L817

А то что там с хваста 0-1 байта в начало переносится.  Мне было так проще сделать.

0


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » управление памятью » Разновидности буферов