Найти - Пользователи
Полная версия: Определение интерпретатора
Начало » Python для новичков » Определение интерпретатора
1
wertklop
Привет всем

Почитав книги и в интернете, если я правильно понял, то питоновский интерпретатор jpython поддерживает многопоточность исполнения кода питона, в отличие от cpython с его GIL'ом. Если запустить установленный по умолчанию интерпретатор, то выдаётся такое:
Python 3.1.2 (r312:79147, Apr 15 2010, 15:35:48) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
как мне узнать, какой у меня установлен интерпретатор и как переназначить для использования по умолчанию?
Андрей Светлов
CPython.
Дался вам этот GIL - плохому танцору ноги мешают.
wertklop
Да, дался!
Мне нужно писать приложение, работающее и использующее многоядерность. По информации в интернете, советуют использовать многопроцессорность на основе модуля multiprocessing, чем многопоточность. Кто писал подобные приложения, дайте свою оценку и мнения по поводу написания этих приложений
Кстати, вы определили по надписи GCC?
Андрей Светлов
По номеру svn версии - я их наизусть помню. Кроме того, jython плотно застрял на 2.5

Многоядерность по факту не очень то и нужна. Не часто встречал программы, эффективно грузящие хотя бы одно ядро.
Но если очень хочется - то да, multiprocessing хорошо помогает. В умелых руках быстр и удобен.
amdlintuxos
Андрей Светлов
советуют использовать многопроцессорность на основе модуля multiprocessing
сам недавно задавался тем же вопросом.
я на серьезных приложениях не проверял, но простой пример работает на ура.
Если будет интересно:
from multiprocessing import Process, Queue
import os, time
from random import randint

def f1(list1, list2):
for l1 in list1:
for l2 in list2:
(x,y) = l2.xy # some load
x*x*x*x*x*x*x # some load

def f2(list1, list2):
for l1 in list1:
l1.render()
for l2 in list2:
l2.render()

class ob():
def __init__(self, (x,y)):
self.xy = (x,y)

def render(self):
(x, y) = self.xy # some load
x*x*x*x*x*x*x # some load


if __name__ == '__main__':
npc_list = []
bullets_list = []

i = 0
while i < 1000:
npc = ob((randint(1,100), randint(1,100)))
npc_list.append(npc)

bullet = ob((randint(1,100), randint(1,100)))
bullets_list.append(bullet)

i += 1


while True:
for case in [0,1]:
if case == 0:
t = time.time()
print "PARALLEL calc."
p1 = Process(target=f1, args=(npc_list, bullets_list))
p1.start()

p2 = Process(target=f2, args=(npc_list, bullets_list))
p2.start()

p3 = Process(target=f1, args=(npc_list, bullets_list))
p3.start()

p4 = Process(target=f2, args=(npc_list, bullets_list))
p4.start()

p1.join()
p2.join()
p3.join()
p4.join()
print "Time taken:", time.time() - t


if case == 1:
t = time.time()
print "SERIAL calc."
f1(npc_list, bullets_list)
f2(npc_list, bullets_list)
f1(npc_list, bullets_list)
f2(npc_list, bullets_list)
print "Time taken:", time.time() - t
время выполнения кода на 4х ядерном атлоне
PARALLEL calc.
Time taken: 0.973960161209
SERIAL calc.
Time taken: 3.24503898621
как видите 3.2х кратное увеличение. Однако уверен что функции которые распределяются по процессорам в моём примере поразному его нагружают, поэтому, в идеале, при выравнивании нагрузок, можно добится результата и получше, но это уже идеализация.
Как мне намекнули на этом форуме GIL в multiprocessing не играет никакой роли.
doza_and
Поддержу: “плохому танцору ноги мешают”.
Многопоточное исполнение может понадобиться в двух случаях:
1 Вам удобнее думать что в программе есть много кусков ()
2 вам надо чтобы быстро что-то посчиталось

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

Во втором случае нужен multiprocessing если надо считать именно интерпретатором.
У multiprocessing есть недостаток - большое время старта процесса - десятки миллисекунд.
Но если вы боретесь за производительность то первое что вы сделаете - откомпилируете критические куски кода и распараллелите все что можно на нижнем уровне, поэтому какой питон и какой модуль использовать - безразлично. Для расчетов можно использовать и готовые распараллеленые библиотеки предметной области - их полно для линейной алгебры. Есть еще конечно http://www.parallelpython.com/ или pyMPI. Но большего эффекта можно добиться только ручками на нижнем уровне.



Могу даже примерно описать что произойдет: Получите от 4 ядер ускорение раза в 2-3 потом подцепите GUDA это приведет к тому, что побежите менять кулер на процессоре и видюшке и покупать новый блок питания. После этого получите 10-30 кратное ускорение :), если будет мало начнете строить grid или умыкнете где-нибудь суперкомпьютер.

Мой опыт показывает - построить счетную систему полностью грузящую 4-8 ядер на cpython - легко.
Андрей Светлов
doza_and, на линуксе multiprocessing.Process стартует 1 мс. Что, конечно, в 6-7 раз хуже чем threading.Thread - но вполне сопоставимо.

А в остальном - все верно.
doza_and
На windows XP SP3 под python 2.6 первый старт multiprocessing.Process был порядка 50 ms (прмерно) последующие 20-30 ms. Наверное это зависит от конфигурации системы, но такие времена конечно могут потребовать применения своеобразной оптимизации алгоритма :(. За информацию про linux Андрей большое спасибо, буду использовать. Там померить просто руки не дошли.
Еще наверное стоит отметить для wertklop что время создания тредов в threading.Thread можно существенно амортизировать используя thread pool который позволит повторно использовать созданные однажды треды.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB