Заставить Linux читать своп обратно в память

28

Ядро Linux выгружает большинство страниц из памяти, когда я запускаю приложение, которое использует большую часть 16 ГБ физической памяти. После завершения приложения каждое действие (ввод команд, переключение рабочих областей, открытие новой веб-страницы и т. Д.) Занимает очень много времени для завершения, потому что соответствующие страницы сначала необходимо прочитать обратно из свопинга.

Есть ли способ заставить ядро ​​Linux копировать страницы из раздела подкачки обратно в физическую память, не касаясь (и не ожидая) каждого приложения? Я запускаю много приложений, поэтому ждать всегда больно.

Я часто использую, swapoff -a && swapon -aчтобы заставить систему реагировать снова, но это очищает страницы от свопинга, поэтому их нужно записать заново при следующем запуске скрипта.

Есть ли интерфейс ядра, возможно, использующий sysfs, чтобы дать команду ядру прочитать все страницы из раздела подкачки?

Редактировать: я действительно ищу способ сделать все из swapcached. (Спасибо, Дероберт!)

[PS serverfault.com/questions/153946/… и serverfault.com/questions/100448/… являются смежными темами, но не затрагивают вопрос о том, как заставить ядро ​​Linux копировать страницы из подкачки обратно в память без очистки подкачки.]

drrossum
источник
Вы хотите, чтобы все операции подкачки были кешем системной памяти? Таким образом, вы хотите образ памяти системы, который вы можете перезагрузить по желанию? По сути, именно так работает гибернация: система записывает свою память на диск, выключает питание и восстанавливает образ при включении питания. Как вы думаете, есть ли шанс, что запрос, следующий за этой веткой, может быть вам полезен? Например, если вам нужно создать образ вашей памяти, отключить обмен, выполнить задачу, а затем восстановить образ и повторить - это то, что вы хотели бы сделать?
mikeserv
Я не думаю, что это оставило бы своп в состоянии подкачки. Таким образом, мне кажется, что ваше предложение является альтернативой для метода swapoff-swapon.
drrossum
Нет, он не кэширует подкачку (что, по общему признанию, немного странно для меня), он кэширует ОЗУ в какой-то момент, который вы считаете наиболее интегральным, а затем выделяет всю системную память какой-то интенсивной задаче, прежде чем восстанавливать кэш, когда задача выполнена Если вы хотите поменяться во время интенсивной задачи, то вы только замедлите эту задачу - вам понадобится дополнительное время, чтобы менять страницы по мере продвижения.
mikeserv

Ответы:

4

На основе программы memdump, изначально найденной здесь, я создал скрипт для выборочного чтения указанных приложений обратно в память. remember:

#!/bin/bash
declare -A Q
for i in "$@"; do
    E=$(readlink /proc/$i/exe);
    if [ -z "$E" ]; then.
        #echo skipped $i;.
        continue;.
    fi
    if echo $E | grep -qF memdump; then.
        #echo skipped $i >&2;.
        continue;.
    fi
    if [ -n "${Q[${E}]}" ]; then.
        #echo already $i >&2;.
        continue;.
    fi
    echo "$i $E" >&2
    memdump $i 2> /dev/null
    Q[$E]=$i
done | pv -c -i 2 > /dev/null

Использование: что-то вроде

# ./remember $(< /mnt/cgroup/tasks )
1 /sbin/init
882 /bin/bash
1301 /usr/bin/hexchat
...
2.21GiB 0:00:02 [ 1.1GiB/s] [  <=>     ]
...
6838 /sbin/agetty
11.6GiB 0:00:10 [1.16GiB/s] [      <=> ]
...
23.7GiB 0:00:38 [ 637MiB/s] [   <=>    ]
# 

Он быстро пропускает неиспользуемую память (гигабайт в секунду) и замедляется при необходимости подкачки.

Vi.
источник
Этот инструмент делает именно то, что я искал. Благодарность!
drrossum
Одна приятная вещь заключается в том, что, по моим наблюдениям, подкачанные страницы копируются в оперативную память, но они не удаляются из подкачки (по крайней мере, большинство из них не удаляются, поскольку использование подкачки лишь незначительно уменьшается). Моя интерпретация заключается в том, что Linux хранит две копии каждой страницы, одну в оперативной памяти и одну в разделе подкачки. Если это обрабатывается правильно, это даже лучше, чем отмена и добавление подкачки снова, потому что это означает, что, когда придется снова поменять местами двойную страницу, больше не будет необходимости в другой копии. Спасибо любому эксперту по ядру, который может подтвердить.
Джованни Масцеллани
11

Это может помочь увеличить /proc/sys/vm/page-cluster(по умолчанию: 3).

Из документации ядра ( sysctl/vm.txt):

страниц кластера

page-cluster контролирует количество страниц, до которых последовательные страницы считываются из свопинга за одну попытку. Это аналог подкачки для чтения кеша страниц. Упомянутая последовательность не в терминах виртуальных / физических адресов, а в последовательности подкачки - это означает, что они были заменены вместе.

Это логарифмическое значение - установка его в ноль означает «1 страница», установка в 1 означает «2 страницы», установка в 2 означает «4 страницы» и т. Д. Ноль полностью отключает чтение подкачки.

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

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

В документации не упоминается ограничение, поэтому, возможно, вы могли бы установить этот абсурдно высокий уровень, чтобы все свопы могли быть прочитаны очень скоро. И, конечно, поверните его обратно к нормальному значению впоследствии.

derobert
источник
Это звучит как полезный обходной путь. Два ручных вмешательства могут быть объединены с командой сна, чтобы сделать это одним пользовательским вмешательством. Но, это не обязательно делает все swapcached очень быстро, поскольку он только читает последовательно со страницы, к которой осуществляется доступ. Это пока лучшее решение. Благодарность!
drrossum
Возможно, это лучшее решение, которое вы получите. Я не слышал об этом раньше, но похоже, что это превращает замену в серию больших IOP, а не в непрерывный набор маленьких IOP, что, вероятно, вызывает проблемы с производительностью. Я был бы законно удивлен, если бы было что-то, что идеально отвечало бы вашей индивидуальной ситуации.
Братчли
В этом отношении, если вы испытываете замедления из-за большого количества последовательных небольших замен, даже просто постоянное изменение page-clusterзначения может улучшить производительность.
Илмари Каронен
5

Вы можете попытаться добавить программы, которые вам больше всего нужны , в cgroup и настроить подкачку так, чтобы при следующем запуске приложения добавленные вами программы были менее вероятными кандидатами на обмен.

Некоторые из их страниц, вероятно, все еще будут заменены, но это может обойти ваши проблемы с производительностью. Большая часть этого, вероятно, просто поведение «останови и запусти», когда многие страницы программы находятся в режиме подкачки, и программе приходится постоянно приостанавливать работу, чтобы свопить ее страницы в ОЗУ, но только с шагом 4 КБ.

В качестве альтернативы, вы можете добавить приложение, которое работает, в cgroup и настроить подкачку так, чтобы приложение использовало файл подкачки чаще всего. Это замедлит работу приложения, но избавит остальную часть системы.

Bratchley
источник
4

Мне кажется, что вы не можете волшебным образом «заставить систему реагировать снова». Вы либо несете штраф, либо читаете страницы обратно из пространства подкачки в память сейчас, либо переносите его позже, но тем или иным способом вы берете это на себя. В самом деле, если вы делаете что-то подобное, swapoff -a && swapon -aвы можете почувствовать больше боли, а не меньше, потому что вы заставляете некоторые страницы копироваться обратно в память, которые в противном случае никогда бы больше не понадобились и в конечном итоге были отброшены без чтения (подумайте: вы выходите из приложения, пока большая часть его кучи выгружается, эти страницы могут быть полностью удалены, даже не возвращаясь в память).

но это очищает страницы от подкачки, поэтому они должны быть записаны снова при следующем запуске сценария.

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

Я думаю, твой swapoff -a && swapon -aтрюк так же хорош, как и все, что ты мог придумать.

Celada
источник
Это двое из нас говорят одно и то же одновременно;)
Златовласка
@goldilocks, да, я видел, как твой ответ появился до того, как мой был готов, но я уже ¾ сделал, поэтому я застрял с ним :-)
Celada
Вы и Златовласка говорите то же самое, но я не верю, что так работает кэширование свопа. Насколько я понимаю, вы можете иметь страницы в разделе подкачки и памяти одновременно. Страница подкачки становится недействительной только после обновления страницы в памяти.
drrossum
Я верю, что ответ, на который вы указали Дэвидом Спиллеттом , верен: вы действительно можете иметь страницу подкачки и ОЗУ одновременно ... но только до тех пор, пока версия ОЗУ не будет изменена. Затем вы должны отказаться от устаревшей копии в свопе. Когда я сказал «почти любая страница, которая будет скопирована обратно из свопа [...], все равно будет изменена», я имел в виду, что я ожидаю, что это происходит в большинстве случаев, поэтому я не ожидаю, что страницы в обоих местах значительная часть стоит беспокоиться.
Селада
Ваш сценарий использования может быть другим: у вас может быть много приложений с большими кучами, которые часто читаются и не записываются. Я чувствую, что у большинства людей нет такого сценария. Но если вы это сделаете, я думаю, вы правы: swapoff -a && swapon -aне будет хорошо для вас. Я думаю, что в этом случае вам нужно что-то, что сканирует /proc/<each-process>/memи читает каждую страницу памяти, чтобы убедиться, что она существует в оперативной памяти. Не знаю, существует ли это.
Селада
0

Здесь очень хорошая дискуссия http://rudd-o.com/ru/linux-and-free-software/tales-from-responsivenessland-why-linux-feels-slow-and-how-to-fix-that которая сводится к уменьшению перестановки, с идеей, что для увеличения воспринимаемой отзывчивости системы следует предотвратить выгрузку кода (и это то, что происходит). Это не совсем ответ на ваш вопрос, но это может помешать появлению проблемы (ваши приложения просто не меняются местами, только неиспользуемые данные и кэш страницы)

Fedxa
источник
Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить здесь основные части ответа и предоставить ссылку для справки.
SLM