Почему процессор Linux замирает при многопоточных записях в память?

Вопрос или проблема

Аппаратные характеристики:

  • ЦП: 64 ядра, 128 потоков, AMD Ryzen Threadripper Pro 5995WX
  • ОЗУ: 512 ГБ, производитель неизвестен, постараюсь предоставить, если нужно

Характеристики Linux:

  • ОС: Ubuntu 22.04.4 LTS
  • Ядро Linux: 5.15.0-119-generic

Я пытаюсь настроить обучение модели с использованием pytorch на сервере Linux, где я наблюдал ухудшение производительности примерно в 10 раз после того, как запустил ресурсоемкую задачу обучения на несколько минут (обучение на 4 GPU с многопоточным загрузчиком данных).

Пытаясь изолировать корневую причину этой проблемы, я разработал минимальный тест на python, воспроизводящий проблему, путем непрерывной записи 1 ГБ данных в ОЗУ. Запуская это с 32 потоками параллельно (ЦП имеет 128 доступных потоков), ЦП зависает через <2 мин, и при прямом снижении количества потоков до 16 или 4, система продолжает зависать (htop "psi some cpu"> 0%) до тех пор, пока не дать ей время на остывание примерно 1 мин. Я провел тест на другом сервере (48 потоков ЦП, 160 ГБ ОЗУ) в течение 10 минут без каких-либо проблем (на этом сервере также работает многопроцессорное обучение без ухудшения производительности).

В отличие от самостийного теста записи в память, я также провел тест производительности с использованием sysbench, записывая 10 ТБ данных с до 96 потоками без каких-либо проблем. Здесь я не совсем понимаю разницу, не записывает ли эта задача данные только в какой-то буфер, не выделяя реально никакой памяти ОЗУ? Я запустил тест с помощью следующей команды:
sysbench --threads=96 --time=0 --memory-block-size=128K --memory-total-size=10T --report-interval=1 --memory-oper=write memory run

Основное наблюдаемое отличие sysbench от моего скрипта на python было в htop, где у sysbench все потоки работали как обычные потоки с нормальным приоритетом/пользовательские потоки (зеленые полосы), в то время как мой скрипт на python вызывал большую часть времени работы в ядре (красные полосы), что, как я понимаю, вызвано большим количеством времени ожидания.

Теперь мой вопрос: дает ли эта диагностика какое-либо представление о том, почему система зависает? Может быть, это проблема с оборудованием ОЗУ или это может быть проблема с ОС? Или какие еще тесты я могу провести, чтобы изолировать корневую причину?


Редактировать:
В следующем вы можете найти минимальный python скрипт:

import time
import numpy as np
import threading

data = np.zeros((1024, 1024, 1024, 1), dtype=np.uint8)

def allocate_memory():
    while True:
        start_time = time.time()
        _ = data * 0
        end_time = time.time()
        print(f"Time: {end_time - start_time:.3f} s")
    
    print(data.shape)

def run_in_threads(num_threads):
    threads = []
    for _ in range(num_threads):
        thread = threading.Thread(target=allocate_memory)
        thread.start()
        threads.append(thread)
    
    for thread in threads:
        thread.join()

if __name__ == "__main__":
    num_threads = 32
    run_in_threads(num_threads)

Кажется, что проблема больше связана с аппаратной неисправностью, чем с ОС Linux. Я запросил немного времени на обслуживание сервера и постарался определить потенциально неисправный модуль ОЗУ, удаляя их по одному.

В конце концов, конкретный модуль не был выявлен, но после удаления двух из четырех мой тестовый скрипт больше не вызывал увеличение информации о давлении (PSI some CPU в htop) и работал плавно. После этого я снова вставил удаленные модули ОЗУ по одному просто для проверки, но сервер с тех пор работает гладко. У меня была задача многопроцессорного обучения с pytorch, работающая всю ночь, без ухудшения производительности.

Я предположу, что один из модулей ОЗУ мог быть неправильно установлен, но не могу сказать это наверняка.

Ответ или решение

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

Анализ производительности

Вы описываете сценарий, в котором процессор AMD Ryzen Threadripper Pro 5995WX с 64 ядрами и 128 потоками значительно замедляет свою работу во время выполнения операций записи в память. При этом, тестовая программа на Python с многопоточными записями ведет к увеличению показателя PSI (Pressure Stall Information) в htop, что указывает на загрузку системы и возможные задержки CPU.

При запуске вашего сценария записи в RAM с 32 потоками, вы заметили, что производительность резко падает, и после этого процессору требуется время на «остывание». Это поведение может быть связано с несколькими факторами:

  1. Система управления памятью: На уровне ядра Linux возможны конфликты при доступе к одной и той же области памяти от разных потоков. Когда потоки пытаются одновременно записать данные в память, это может вызвать блокировки и ожидания, особенно если они работают с одним и тем же регионом памяти.

  2. Конфликты кэша: Учитывая, что у вас имеется 128 потоков, конфликт кэша может увеличиваться при записи многопоточных данных, и процессор может тратить больше времени на согласование данных между ядрами.

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

  4. Ожидания ввода-вывода: Если ваш тест ведёт к частым обращениям к памяти, это может привести к значительному увеличению времени ожидания ввода-вывода.

Сравнение с sysbench

Вы также упомянули о тестировании с помощью sysbench, которое не показало таких проблем. Основные различия заключаются в том, что sysbench может использовать более оптимизированный подход, который минимизирует количество блокировок и конфликтов, работает с памятью более эффективно и может не выделять память «физически», используя буферы. Кроме того, в sysbench потоки могут быть более равномерно распределены и, вероятно, меньше влияют друг на друга.

Проблемы с оборудованием

Ваши наблюдения о том, что после изменения конфигурации ОЗУ система начала работать более стабильно, указывают на возможные проблемы с самим оборудованием. Вот некоторые шаги, которые можно предпринять для дальнейшего анализа:

  1. Проверка ОЗУ: Проведите полное тестирование модулей памяти с использованием утилит, таких как Memtest86, чтобы исключить возможность неполадок в RAM.

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

  3. Параметры BIOS/UEFI: Убедитесь, что настройки памяти в BIOS/UEFI оптимизированы для вашей конфигурации. Проверьте работу РАМ на номинальных частотах и таймингах.

  4. Изоляция модуля памяти: Если есть возможность, тестируйте систему с разными комбинациями модулей памяти, чтобы определить их влияние на стабильность.

Заключение

Ваш опыт действительно указывает на сложные взаимодействия между аппаратным обеспечением и операционной системой при работе с многопоточными задачами. Тестирование с sysbench, помимо частных изменений в конфигурации серверов, показывает, что неправильная организация доступа к памяти на высоких нагрузках может привести к серьёзным проблемам. Таким образом, негативные результаты вашего теста могут быть связаны как с программными, так и с аппаратными ограничениями, и, возможно, требуют дальнейшего исследования. Если подобные проблемы повторяются, рекомендуется обратиться к профессиональному технику, который сможет провести детальную диагностику.

Оцените материал
Добавить комментарий

Капча загружается...