Почему dd с флагом 'direct' (O_DIRECT) так значительно быстрее?
У меня есть сервер с конфигурацией RAID50 из 24 дисков (две группы по 12), и если я запускаю:
dd if=/dev/zero of=ddfile2 bs=1M count=1953 oflag=direct
Я получил:
2047868928 bytes (2.0 GB) copied, 0.805075 s, 2.5 GB/s
Но если я бегу:
dd if=/dev/zero of=ddfile2 bs=1M count=1953
Я получил:
2047868928 bytes (2.0 GB) copied, 2.53489 s, 808 MB/s
Я понимаю, что O_DIRECT заставляет обойти кеш страницы. Но, насколько я понимаю, обход кеша страниц в основном означает избегание использования memcpy. Тестирование на рабочем столе с использованием инструмента полосы пропускания У меня в худшем случае полоса пропускания последовательной записи в память составляет 14 ГБ / с, и я полагаю, что на более новом более дорогом сервере пропускная способность должна быть еще лучше. Итак, почему дополнительный memcpy вызывает>2x замедление? Неужели при использовании кеша страниц гораздо больше задействовано? Это нетипично?
1 ответ
В oflag=direct
если вы даете ядру возможность записывать данные сразу, а не ждать, пока буфер достигнет порогового значения / тайм-аута для принудительного нажатия / синхронизации (что означает, что с меньшей вероятностью он будет задерживаться после синхронизации несвязанной данные), и вы сохраняете работу ядра (без дополнительных копий из пользовательского пространства в ядро, нет необходимости выполнять большинство операций управления буферным кешем). Этот гигантский размер блока (1М), вероятно, больше, чем размер блока RAID, поэтому ввод-вывод будет разделен внутри ядра, а эти меньшие части будут передаваться параллельно, таким образом, объединение, которое вы получите от буферизованной обратной записи с крошечным вводом-выводом, выиграло ' не стоит много В некоторых случаях очистка буферов быстрее, чем их можно очистить, приведет к тому, что программа сгенерирует грязные буферы, заставляющие ждать, пока давление на произвольных пределах не будет снято (см. SUSE "Низкая производительность записи на серверах SLES 11/12 с большим объемом ОЗУ"), Учитывая все вышесказанное, ЕСЛИ вы максимизировали один ЦП во время исходной буферизованной копии (но диск мог обрабатывать большую пропускную способность), то выполняли O_DIRECT
копирование должно выполняться быстрее, так как для пользовательского пространства / обслуживания дискового ввода-вывода доступно больше процессорного времени из-за уменьшения нагрузки на ядро.
Итак, почему дополнительный memcpy вызывает>2x замедление?
Это не просто дополнительный memcpy для каждого ввода / вывода - подумайте обо всех дополнительных механизмах кэширования, которые необходимо поддерживать.
Неужели при использовании кеша страниц гораздо больше задействовано?
Да, но если ваша программа не может генерировать данные достаточно быстро, а процессор настолько перегружен, что не может загружать диск достаточно быстро, то обычно это не проявляется и не имеет значения.
Это нетипично?
Нет, ваш результат довольно типичен для той рабочей нагрузки, которую вы использовали. Я предположил бы, что это был бы другой результат, если бы размер блока был крошечным (например, 512).
Сводка: ваш шаблон ввода-вывода на самом деле не выигрывает от буферизации (объемы ввода-вывода огромны, данные не используются повторно, поток ввода-вывода последовательно), поэтому вы находитесь в оптимальном сценарии для O_DIRECT
Быть быстрее. Посмотрите эти слайды от оригинального автора LinuxO_DIRECT
за оригинальную мотивацию за этим.