2013-08-05 1 views
12

Я столкнулся с незначительной проблемой ЦВД после выполнения некоторых тестов на архитектуре 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 потока, управляющих одним и тем же объектом памяти.

Для этого мне нужно знать:

  1. , как выяснить, какой сокет данный питона процесс (нить) работает на.
  2. как назначить пул памяти на этом конкретном сокете для процесса python (некоторый предел malloc или аналогичный, чтобы сумма пулов памяти не наводила пул памяти из одного сокета на другой)
  3. Вещи, которые я не думал из.

Но я не могу найти ссылки в документах 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:

+2

Не могли бы вы объяснить свой вопрос немного более контекстом? Я бы наивно ответил, что процесс Python не может работать многоядерным, поэтому вы должны говорить о 80 (или 160) независимых процессах здесь. Прикрепление их к конкретным сердечникам может быть достигнуто, например. с 'taskset', в Linux (см.' man tasklet'). –

+1

zeromq разрешает вам загружать рабочую нагрузку на все ваши гиперпотоки, но это автоматически не означает, что создаваемые объекты памяти остаются с каждым потоком. –

+0

Хорошо. Все идет нормально. Я обнаружил, что с помощью python Threading я могу заблокировать память Threading.local(). Теперь мне просто нужно прикрепить поток к ядру. Является ли это работой C или ядра? –

ответ

4

Вы можете недооценить проблему, нет сверхлегкого способа выполнить то, что вы хотите. В качестве общего руководства вам необходимо работать на уровне операционной системы, чтобы настроить все так, как вы хотите. Вы хотите работать с так называемой «близостью к процессору» и «сродством к памяти», и вам нужно много думать о своей системной архитектуре, а также о вашей архитектуре программного обеспечения, чтобы все было в порядке. В реальном HPC названные «сродства» обычно обрабатываются библиотекой MPI, такой как Open MPI. Возможно, вы захотите рассмотреть возможность использования одного и позволить вашим различным процессам обрабатывать эту библиотеку MPI. Интерфейс между операционной системой, библиотекой MPI и Python может быть предоставлен пакетом mpi4py.

Вам также необходимо получить представление о потоках и процессах и настройке ОС прямо. В то время как для планировщика времени ЦП поток представляет собой задачу, которая должна быть запланирована, и поэтому теоретически может иметь индивидуальную близость, мне известны только маски близости для целых процессов, то есть для всех потоков в рамках одного процесса.Для управления доступом к памяти NUMA (неравномерный доступ к памяти) является правильным ключевым словом, и вы можете посмотреть в http://linuxmanpages.com/man8/numactl.8.php

В любом случае вам нужно прочитать статьи о теме близости и, возможно, захотите начать чтение в Открытый FAQs MPI о сродстве CPU/памяти: http://www.open-mpi.de/faq/?category=tuning#paffinity-defs

в случае, если вы хотите достичь своей цели без использования библиотеки MPI, заглядывать в пакеты util-linux или schedutils и numactl вашего дистрибутив Linux для того, чтобы получить полезные инструменты командной строки, такие как taskset, что вы могли бы, например, вызов из Python, чтобы установить маски соответствия для определенных идентификаторов процесса.

Эта статья, кажется, наглядно описывает, как библиотека MPI может быть полезной с вопросом:

http://blogs.cisco.com/performance/open-mpi-v1-5-processor-affinity-options/

Этот SO ответ описывает, как вы разрез`ать вашу аппаратную архитектуру: https://stackoverflow.com/a/11761943/145400

Вообще, я задаваясь вопросом, является ли машина, на которую вы подаете заявку, является правильной для этой задачи или, если вы, возможно, оптимизируетесь не в том направлении. Если вы отправляете сообщение в пределах одной машины и ограничиваете пределы пропускной способности памяти, я не уверен, что ZMQ (через TCP/IP, правильно?) Является правильным инструментом для выполнения обмена сообщениями. Возвращаясь к MPI, интерфейс передачи сообщений для приложений HPC ...

+0

Спасибо за подробный ответ. Это займет некоторое время, чтобы следить за ссылками. –

+0

Вы еще не приняли решение? –

+1

MPI lib - это * the * place to go. –

0

Просто интересно, не может ли это быть связано с использованием удаленных объектов python - это может стоить расследования, но, к сожалению, у меня нет доступа к такому оборудованию.

Как объясняется в documentation, в то время как пирог часто используется для распределения работы по нескольким машинам в сети, он также может использоваться для обмена обработкой между ядрами на одной машине.

На нижнем уровне Pyro - это всего лишь форма межпроцессного общения. Таким образом, везде, где вы могли бы использовать более примитивную форму IPC (например, простые сокеты TCP/IP) между компонентами Python, вы могли бы использовать вместо этого Pyro.

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

+0

Можете ли вы объяснить свою идею немного подробнее? –