Я столкнулся с незначительной проблемой ЦВД после выполнения некоторых тестов на архитектуре 80core (160HT) Nehalem с 2TB памяти DRAM:Как связать потоки с ядрами с заданными объектами пула памяти? (80 ядра Nehalem архитектура 2 ТБ ОЗУ)
Сервер с более чем 2-х розеток начинает киоска lot (delay), поскольку каждый поток начинает запрашивать информацию об объектах в «неправильном» сокете, то есть запросы идут от потока, который работает с некоторыми объектами в одном сокете, чтобы извлекать информацию, которая на самом деле находится в DRAM на другом сокете.
Ядра отображаются на 100%, хотя я знаю, что они ждут, когда удаленный сокет вернет запрос.
Поскольку большая часть кода выполняется асинхронно, гораздо проще переписать код, поэтому я могу просто анализировать сообщения из потоков на одном сокете, чтобы потоки других (без блокировки ожидания). Кроме того, я хочу блокировать каждый поток в пулах памяти, поэтому я могу обновлять объекты, а не тратить время (~ 30%) на сборщик мусора.
Отсюда вопрос:
Как закрепить нити, чтобы сердечники с заранее заданными объектами пула памяти в Python?
Побольше контекст:
Python не имеет никаких проблем работают многоядерной, когда вы положили ZeroMQ в середине и сделать искусство из передачи сообщений между пулом памяти под управлением каждым ZMQworker. На ZMQ 8M msg/second это внутреннее обновление объектов занимает больше времени, чем трубопровод может быть заполнен. Все это описано здесь: http://zguide.zeromq.org/page:all#Chapter-Sockets-and-Patterns
Итак, с небольшим упрощением, я создаю 80 ZMQworkerprocesses и 1 ZMQrouter и загружаю контекст с большим роем объектов (на самом деле 584 миллиона объектов). Из этой «начальной точки» объекты должны взаимодействовать, чтобы завершить вычисление.
Это идея:
- Если «объект X» должен взаимодействовать с «Объект Y» и доступен в локальный пул памяти питона-нить, то взаимодействие должно быть сделано непосредственно.
- Если «Объект Y» НЕ доступен в том же пуле, то я хочу, чтобы он отправил сообщение через ZMQrouter, и пусть маршрутизатор возвращает ответ в некоторый более поздний момент времени. Моя архитектура не блокирует, так что то, что происходит в конкретном потоке python, продолжается, не дожидаясь ответа zmqRouters. Даже для объектов в одном и том же сокете, но на другом ядре, я предпочел бы НЕ взаимодействовать, поскольку я предпочитаю иметь чистые обмены сообщениями вместо того, чтобы иметь 2 потока, управляющих одним и тем же объектом памяти.
Для этого мне нужно знать:
- , как выяснить, какой сокет данный питона процесс (нить) работает на.
- как назначить пул памяти на этом конкретном сокете для процесса python (некоторый предел malloc или аналогичный, чтобы сумма пулов памяти не наводила пул памяти из одного сокета на другой)
- Вещи, которые я не думал из.
Но я не могу найти ссылки в документах python о том, как это сделать и на google. Я должен искать неправильную вещь.
Update:
Что касается вопроса «почему использовать ZeroMQ на архитектуре MPI?», Пожалуйста, прочитайте тему: Spread vs MPI vs zeromq? как приложения я работаю проектируется для распределенного развертывания, даже если он является протестированы на архитектуре, где MPI - более подходит.
Обновление 2:
Что касается вопроса:
"Как резьбы ниппеля для ядер с заданными пулов памяти в Python (3)" Ответ в psutils:
>>> import psutil
>>> psutil.cpu_count()
4
>>> p = psutil.Process()
>>> p.cpu_affinity() # get
[0, 1, 2, 3]
>>> p.cpu_affinity([0]) # set; from now on, this process will run on CPU #0 only
>>> p.cpu_affinity()
[0]
>>>
>>> # reset affinity against all CPUs
>>> all_cpus = list(range(psutil.cpu_count()))
>>> p.cpu_affinity(all_cpus)
>>>
Работник может быть привязан к ядру, посредством которого NUMA может быть эффективно использована (найдите свой тип процессора, чтобы убедиться, что он является архитектурой NUMA!)
Второй элемент - определить пул памяти. Это можно сделать также с помощью psutils или resource library:
Не могли бы вы объяснить свой вопрос немного более контекстом? Я бы наивно ответил, что процесс Python не может работать многоядерным, поэтому вы должны говорить о 80 (или 160) независимых процессах здесь. Прикрепление их к конкретным сердечникам может быть достигнуто, например. с 'taskset', в Linux (см.' man tasklet'). –
zeromq разрешает вам загружать рабочую нагрузку на все ваши гиперпотоки, но это автоматически не означает, что создаваемые объекты памяти остаются с каждым потоком. –
Хорошо. Все идет нормально. Я обнаружил, что с помощью python Threading я могу заблокировать память Threading.local(). Теперь мне просто нужно прикрепить поток к ядру. Является ли это работой C или ядра? –