Skip to main content
  • Place orders quickly and easily
  • View orders and track your shipping status
  • Enjoy members-only rewards and discounts
  • Create and access a list of your products

Пять способов повысить быстродействие жестких дисков в Linux

Summary: Здесь вы найдете 5 способов повышения производительности жесткого диска в Linux.

This article applies to   This article does not apply to 

Symptoms

Пять способов повысить быстродействие жестких дисков в Linux 

Cause

-

Resolution

  1. Обход PAGE-CACHE для данных, доступных только для чтения.
  2. Обход PAGE-CACHE для больших файлов.
  3. IF (CPU-BOUND), THEN SCHEDULER == NO-OP;
  4. Размер блока: Чем больше, тем лучше
  5. Синхронизация и асинхронность (а также чтение и запись)

 

1. Обход PAGE-CACHE для данных, доступных только для чтения.

В начало

Страничный кэш кэширует недавно открытые страницы с жесткого диска, тем самым сокращая время поиска для последующих обращений к тем же данным. Страничный кэш не повышает производительность при первом доступе к странице с жесткого диска. Таким образом, если приложение собирается прочитать файл один раз и только один раз, то лучше обойти кэш страницы. Это возможно с помощью флага O_DIRECT. Это означает, что ядро не учитывает эти конкретные данные для кэша страниц. Уменьшение конкуренции за кэш означает, что другие страницы (к которым будут обращаться многократно) имеют больше шансов остаться в кэше страниц. Это улучшает коэффициент попадания в кэш, обеспечивая более высокую производительность.

void ioReadOnceFile()
{
/* Использование direct_fd и direct_f обходит кэш страниц ядра.
* - direct_fd — низкоуровневый файловый дескриптор
* - direct_f - это файловый поток, похожий на тот, который возвращает fopen()
* ПРИМЕЧАНИЕ: Используйте getpagesize() для определения буферов оптимального размера.
*/

int direct_fd = open("имя файла", O_DIRECT | O_RDWR);
FILE *direct_f = fdopen(direct_fd, "w+");

/* прямой дисковый ввод-вывод выполняется ЗДЕСЬ*/

fclose(f);
close(fd);
}


2. Обход PAGE-CACHE для больших файлов.

В начало

Рассмотрим случай чтения в большом файле (т.е. базе данных), состоящем из огромного количества страниц. Каждая последующая страница, к которой вы обращаетесь, попадает в кэш страниц только для того, чтобы быть выброшенной позже, по мере прочтения все большего и большего количества страниц. Это значительно снижает коэффициент попадания в кэш. В этом случае страничный кэш не обеспечивает никакого прироста производительности. Следовательно, при доступе к большим файлам лучше обойти страничный кэш.

void ioLargeFile()
{
/* Использование direct_fd и direct_f обходит кэш страниц ядра.
* - direct_fd — низкоуровневый файловый дескриптор
* - direct_f - это файловый поток, похожий на тот, который возвращает fopen()
* ПРИМЕЧАНИЕ: Используйте getpagesize() для определения буферов оптимального размера.
*/

int direct_fd = open("largefile.bin", O_DIRECT | O_RDWR | O_LARGEFILE);
FILE *direct_f = fdopen(direct_fd, "w+");

/* прямой дисковый ввод-вывод выполняется ЗДЕСЬ*/

fclose(f);
close(fd);
}

3. IF (CPU-BOUND), THEN SCHEDULER == NO-OP;

В начало

Планировщик ввода-вывода оптимизирует порядок операций ввода-вывода, помещаемых в очередь на жесткий диск. Так как время поиска — это самый большой штраф для жесткого диска, большинство планировщиков ввода-вывода пытаются свести его к минимуму. Это реализовано как вариант алгоритма лифта, т.е. переупорядочение случайно упорядоченных запросов из многочисленных процессов в порядок, в котором данные находятся на жестком диске, требует значительного количества процессорного времени.

Некоторые задачи, связанные со сложными операциями, как правило, ограничены тем, насколько быстро ЦП может обрабатывать огромные объемы данных. Сложный планировщик ввода-вывода, работающий в фоновом режиме, может потреблять драгоценные циклы процессора, тем самым снижая производительность системы. В этом случае переход на более простой алгоритм, например, no-op, снижает нагрузку на процессор и может повысить производительность системы.
echo noop > /sys/block//queue/scheduler

 


4. Размер блока: Чем больше, тем лучше

В начало

Хотя это в конечном итоге приведет к выполнению работы, это определенно не самый оптимальный способ. С точки зрения ядра, наиболее оптимальным размером для запросов ввода-вывода является размер блока файловой системы (т.е. размер страницы). Поскольку весь ввод-вывод в файловой системе (и кэш страниц ядра) осуществляется в виде страниц, приложению имеет смысл также выполнять передачу в количестве, кратном размеру страницы. Кроме того, с учетом того, что в настоящее время в жесткие диски используются многосегментные кэши, можно было бы получить огромную выгоду, выполняя ввод-вывод в размерах, кратных размеру блока.


Для определения оптимального размера
блока можно использовать следующуюкоманду: --printf="bs=%s optimal-bs=%S\n" --file-system /dev/


5. Синхронизация и асинхронность (а также чтение и запись)

В начало

Когда приложение инициирует чтение ввода-вывода SYNC, ядро ставит в очередь операцию чтения данных и возвращает ее только после обратного считывания всего блока запрошенных данных. В течение этого периода ядро помечает процесс приложения как заблокированный для ввода-вывода. Другие процессы могут использовать ЦП, что в целом повышает производительность системы.

Когда приложение инициирует запись ввода-вывода SYNC, ядро помещает в очередь операцию записи для данных, помещая процесс приложения в заблокированный ввод-вывод. К сожалению, это означает, что процесс текущего приложения заблокирован и не может выполнять какую-либо другую обработку (или ввод-вывод, если уж на то пошло) до завершения этой операции записи.

Когда приложение инициирует асинхронное чтение ввода-вывода, функция read() обычно возвращается после чтения подмножества большого блока данных. Приложению необходимо многократно вызывать read() с размером данных, оставшихся для чтения, до тех пор, пока все необходимые данные не будут считаны. Каждый дополнительный вызов read приводит к некоторым накладным расходам, так как он вводит переключение контекста между пользовательским пространством и ядром. Реализация замкнутого цикла для многократного вызова read() приводит к потере циклов процессора, которые могли бы быть использованы другими процессами. Следовательно, обычно блокировка реализуется с помощью select() до тех пор, пока следующий read() не вернет ненулевые байты считывания. т.е. ASYNC блокируется так же, как и SYNC read.

Когда приложение инициирует асинхронную запись ввода-вывода, ядро обновляет соответствующие страницы в кэше страниц и помечает их как «грязные». Затем элемент управления быстро возвращается в приложение, которое может продолжить работу. Данные сбрасываются на жесткий диск позже, в более оптимальное время (при низкой нагрузке на ЦП) более оптимальным способом (последовательная групповая запись).

Следовательно, SYNC-чтение и ASYNC-запись , как правило, являются хорошим вариантом, поскольку они позволяют ядру оптимизировать порядок и время базовых запросов ввода-вывода.

 

 

 

 

 

 

 

 

 

 

Affected Products

Red Hat Enterprise Linux Version 5, Red Hat Enterprise Linux Version 6, Red Hat Enterprise Linux Version 7, Red Hat Enterprise Linux Version 9, Red Hat Enterprise Linux Version 8
Article Properties
Article Number: 000140396
Article Type: Solution
Last Modified: 16 Aug 2024
Version:  4
Find answers to your questions from other Dell users
Support Services
Check if your device is covered by Support Services.