Каждый вызов read()
и write()
требует системного вызова (для связи с ядром) плюс время для фактического копирования в (или из) пространство памяти ядра.
Сам системный вызов накладывает фиксированные (на вызов) накладные расходы / затраты, в то время как стоимость копирования данных, конечно, пропорциональна количеству данных, которые необходимо скопировать.
Следовательно, если у вас read()
/ write()
очень маленькие буферы, накладные расходы на выполнение системного вызова будут относительно высокими по сравнению с количеством байтов копируемых данных; и поскольку вам придется совершать большое количество вызовов, общее время выполнения будет больше, чем если бы вы делали большие переводы.
Вызов read()
/ write()
меньшее количество раз с большими буферами позволяет системе амортизировать накладные расходы системного вызова на большее количество байтов на вызов, избегая этой неэффективности. Тем не менее, в какой-то момент, когда размеры увеличиваются, накладные расходы на системные вызовы становятся совершенно незначительными, и в этот момент эффективность программы полностью зависит от стоимости передачи данных, которая определяется скоростью аппаратного обеспечения. Вот почему вы видите выравнивание производительности по мере увеличения размеров.
read()
и write()
не накапливают небольшие записи вместе, поскольку они представляют собой прямые системные вызовы. Если вы хотите, чтобы небольшие операции чтения / записи были буферизованы таким образом, среда выполнения C предоставляет оболочки fread()
и fwrite()
, которые сделают это для вас внутри вашего пространства процессов.