LINUX.ORG.RU

[python][thread][process]Что выбрать для распараллеливания задач?

 , ,


0

1

Задачи будут интерактивные с обращением к bd и вычислениями.
Провел небольшие тесты, в которых сначала тестировал пачку потоков параллельно выполняющих вот эту функцию:

def test():
	for i in xrange(10000):
		if 1<rnd.randint(1,100)<50:
			math.exp(rnd.randint(1, 700))
		else:
			math.exp(rnd.randint(-700, -1))
Затем сделал подобное с процессами и в конце провел тест без распараллеливания
Вот результаты:
INFO:test1:Result for 100 threads:>> 13.3729000092s
INFO:test1:Result for 100 process:>> 7.26567387581s
INFO:test1:Result for 100 tasks in 1 process:>> 12.6496989727s
INFO:test1:Result for 200 threads:>> 26.8068709373s
INFO:test1:Result for 200 process:>> 13.8837189674s
INFO:test1:Result for 200 tasks in 1 process:>> 24.7985720634s
INFO:test1:Result for 300 threads:>> 40.9965510368s
INFO:test1:Result for 300 process:>> 20.5542001724s
INFO:test1:Result for 300 tasks in 1 process:>> 37.2940359116s
INFO:test1:Result for 400 threads:>> 52.8284330368s
INFO:test1:Result for 400 process:>> 27.4708259106s
INFO:test1:Result for 400 tasks in 1 process:>> 49.3902859688s
INFO:test1:Result for 500 threads:>> 66.4858000278s
INFO:test1:Result for 500 process:>> 34.7022809982s
INFO:test1:Result for 500 tasks in 1 process:>> 63.8571689129s
INFO:test1:Result for 600 threads:>> 81.4805150032s
INFO:test1:Result for 600 process:>> 41.375150919s
INFO:test1:Result for 600 tasks in 1 process:>> 73.8992960453s
INFO:test1:Result for 700 threads:>> 93.8431408405s
INFO:test1:Result for 700 process:>> 48.697218895s
INFO:test1:Result for 700 tasks in 1 process:>> 86.1682038307s
INFO:test1:Result for 800 threads:>> 107.462379217s
INFO:test1:Result for 800 process:>> 58.9401319027s
INFO:test1:Result for 800 tasks in 1 process:>> 97.9579291344s
INFO:test1:Result for 900 threads:>> 120.639883041s
INFO:test1:Result for 900 process:>> 62.7911670208s
INFO:test1:Result for 900 tasks in 1 process:>> 111.479810953s
INFO:test1:Result for 1000 threads:>> 134.574063063s
INFO:test1:Result for 1000 process:>> 69.4446690083s
INFO:test1:Result for 1000 tasks in 1 process:>> 127.043555975s
(Еще нужно провести тест с пулами, когда количество потоков/процессов меньше количества задач)
Мне очень порадовало, что процессы вдвое(!!!!) быстрее многопоточного и последовательно выполняющихся задач.
Теперь сами вопросы:
В чем подвох процессов?(заметил сильную потерю отзывчивости при генерации свыше 500 процессов)
Почему потоки вдвое медленнее?
(Думаю будут еще вопросы)

★★★★★

Последнее исправление: deterok (всего исправлений: 1)

Ответ на: комментарий от AIv

Сервер...
Запросы...
Хотел greenlet'ы использовать, но с ними не сложилось.(Почитал про проблемы с ними и решил не использовать)
Вот теперь вручную распараллеливаю запросы.
Сейчас вот думаю, стоит ли делать пул потоков или пул процессов.

deterok ★★★★★
() автор топика

как видно у тебя только 2 ядра процессора - отсюда паралелить больше чем на 2-3 треда/процесса смысла практически нет

ae1234 ★★
()
Ответ на: комментарий от ae1234

Я уже подумал об этом + добавлю возможность задать руками, вдруг неправильно кол-во ядер определит.

deterok ★★★★★
() автор топика

прежде всего - man GIL. а потом смотри на PyPy, 0MQ IPC, Numpy. И да, питон не для вычислений.

iSlava
()
Ответ на: комментарий от deterok

в питоне благодаря global lock'у в один момент времени работает только один поток, поэтому если хочешь скорости, то используй процессы

Reset ★★★★★
()
Ответ на: комментарий от deterok

Сервер... Запросы...

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

AIv ★★★★★
()
Ответ на: комментарий от ae1234

даже на другой - выше 8-16-32 не найдеш

однако

...
processor       : 47
...
Но для подобных задач, когда подавляющее число тредов висит в ожидании данных, это наверное и не важно?

AIv ★★★★★
()
Ответ на: комментарий от AIv

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

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Как сильно повлияет на работу системы частая генерация и уничтожения процессов

По скромному личному опыту - влияет плохо. Скажем в гнуплоте я делал хитровыкрученное построение графиков, так вот на каждый вызов system уходило 0.15 сек. Пришлось все переделывать, ибо суммарно тормозило ощутимо.

Но, Вы похоже строите велосипед. Это позволительно в случае дилетанта вроде меня - у меня подобные задачи несравнимо проще, и мне выгодней заюзать start_new_thread и не забивать себе голову всякой ерундой. В Вашем случае, если все эти изыски оправданы (т.е. Вы не занимаетесь преждевременной оптимизацией - тупое решение с тредами не обеспечивает нужной производительности), надо брать готовое решение. То что они есть я уверен, надо просто погуглить/спросить у baverman, true_admin или еще кого нить из спецов.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Думаю все же придется использовать greenlets:(

deterok ★★★★★
() автор топика
Ответ на: комментарий от AIv

Решил сделать все на тредах и на всякий случай сделать возможность работы с процессами, в будущем буду тестировать greenlet'ы и если тесты не обрадуют, то тестировать pypy+stackless. Фронт работ обширный, многое предстоит еще навоять. Всем спасибо за помощь.

deterok ★★★★★
() автор топика
Ответ на: комментарий от AIv

Это да. Ой, чуть не забыл спросить, может есть готовая библиотека/модуль с пулом тредов? Пол гугла обшарил и нашел вот это чудо

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Ой, чуть не забыл спросить, может есть готовая библиотека/модуль с пулом тредов?

Наверняка есть, и не одна, но я с ними не работал. Я в этих вопросах не особо разбираюсь, у меня неск иной уклон;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv

Нашел еще лучше)
В данном случае маньяк вкрутил в свою библиотеку logging(зачем? принта мало было?).
Такой вопрос: что если сделать потоки постоянно висящими в памяти? И ожидающими события(например добавления в очередь нового элемента). Память занята, потоки много процессорного времени в простое не едят. Единственный недостаток системы плох тем, что я не знаю как забить поток. Его вообще реально забить? Или как то прервать ожидание события?

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

что если сделать потоки постоянно висящими в памяти?

А сколько их Вам надо вообще?;-)

Единственный недостаток системы плох тем, что я не знаю как забить поток.

Снаружи? Ну Гвидо-ван-Россум и Ко про это молчат. Точнее: • Невозможно прервать выполнение метода acquire() объектов, предназначенных для блокировки, — исключение KeyboardInterrupt будет сгенерировано только после захвата объекта.

Ну это про блокировки, вопрос в том на чем он там у Вас висит и ждет...

AIv ★★★★★
()
Ответ на: комментарий от AIv

Надо штук 2-100, все будет завистиь от тестов.
P.S. Автор pythonthreadpool неадекватен кажись, у него библиотека logging в модуль встроена лишь для того, что бы тесты логировались :)
О том, что эту библиотеку могут использовать и другии и не для тестов он не думал.

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

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Как вообще на этом svn ветку новую сделать?

Загрузить рабочую копию и завести новый репозиторий?;-)

AIv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.