Почему 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 за оригинальную мотивацию за этим.

Другие вопросы по тегам