Чому названа труба така повільна, як запис у файл?


18

Я намагаюся зрозуміти, як працюють названі труби, щоб я міг впорядкувати одностороннє міжпроцесорне спілкування. Я очікую певних накладних витрат через копіювання даних у круговий буфер, який, я вважав би, зберігається в оперативній пам'яті, і тому я очікував, що труба буде набагато швидшою, ніж запис у файл (адже оперативна пам'ять набирає величини швидше, ніж диск).

Натомість я виявив, що названа труба (або анонімна труба) приблизно з тією ж швидкістю, що і файл. Це на робочому столі 3 ГГц із звичайним дисковим накопичувачем (не твердотілим), на якому працює Ubuntu Linux. Ось спрощена програма тестування в Python:

import sys
import time
import random

megabyte = "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for x in range(1024**2))

while True:
    before = time.time()
    sys.stdout.write(megabyte)
    after = time.time()
    sys.stderr.write("{} microseconds\n".format(1e6 * (after - before)))

Трубопроводи прямо до /dev/null:

python test.py > /dev/null

дає 2,1 мікросекунди (постійні) на кожен мегабайт.

Передача файлу:

python test.py > /tmp/testout.txt

стрибає між 500 мікросекундами і 930 мікросекундами (чим більше значення стає більш поширеним, оскільки файл стає більшим --- імовірно, він шукає місця на диску).

Тоді названа труба:

mkfifo testpipe
cat testpipe > /dev/null &
python test.py > testpipe

виходить 640 мікросекунд (константа) і безіменна труба:

python test.py | cat > /dev/null

також дає 650 мікросекунд (константа).

Хтось може пояснити, чому швидкість труби більше нагадує швидкість файлу, ніж /dev/nullшвидкість? Можливо, у мене десь є перемикач, який говорить: "запустіть труби через файловий буфер, а не буфер на основі оперативної пам'яті", і чи можу я змінити цей перемикач? Це може бути варіант ядра чи змінна оболонки?

Інша інтерпретація: припустимо, що вихід диска підскакує між 500 та 930 мікросекундами, оскільки 500 просто трубопровід, а 930 - це фактично запис. Тоді 500 ~ 640 для трубопроводів в обох випадках рівнозначні. Однак, згідно з цією інтерпретацією, чому між трубопроводом і власне записом на диск є лише два фактори? Веб-сайти, які розповідають про диски оперативної пам’яті, кажуть, що диски оперативної пам’яті в 50-200 разів швидші, ніж жорсткі диски.


1
Написання в /dev/nullнасправді є досить дешевим, тоді як писати в будь-якому іншому місці - будь то файл, FIFO, труба чи що завгодно - набагато дорожче, оскільки для цього потрібно "багато" зусиль для обробки.
glglgl

Відповіді:


31

Ви не бачите жодної переваги від продуктивності, оскільки ви фактично не потрапляєте на диск під час використання файлу - дані на шляху до диска, але потоці виконання не потрібно чекати, поки він приземлиться, тож ви насправді не бачимо швидкості покарання удару диска.

Якщо ви хочете дочекатися завершення операції з диском, щоб побачити, наскільки повільніше виходить, зателефонуйте sync()(як це залежить від вашої версії python, дивіться тут ) - ви будете дивитись на десятки тисяч мікросекунд лише для того, щоб ваш диск кілька разів спробуйте виписати файл (припустимо, що у ньому немає кешу швидкого запису, як у контролері RAID).


Коли ми перестаємо турбуватися про час пошуку наших блокових пристроїв? :)
EEAA

5
@EEAA Усі SSD, постійно.

1
Ви маєте рацію: із часом запису sync()на диск стає в середньому 74000 мікросекунд. ( flush()Я робив в одному варіанті свого тесту, не робив цього.) Тож моя інтерпретація того, що 500 ~ 640 мікросекунд на мегабайт насправді є трубопровідна, дякує.
Джим Піварський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.