# Такой медленный Питон в Gentoo или это сама Gentoo?? :-/

## Balancer

В общем, наткнулся тут на такую бяку. P4-3200, Gentoo, python-2.5. Имеем примитивную программку по генерации тучи тредов:

```

#!/usr/bin/env python 

# -*- coding: utf-8 -*- 

import threading

import time

def proc(n):

    time.sleep(1)

for i in xrange(10000):

    threading.Thread(target=proc, name="t"+str(i), args=[i]).start()

```

Время работы - 42 секунды.

Эта же программа в Питоне под Убунтой на P4-2800 (а также в Windows XP) работает... 1.4сек!

У кого какие результаты? Что крутить?

Самое неприятное, что эта скорость воспроизводится на трёх машинах с Gentoo.

При сборке - ничего экстремального:

1:

```

CFLAGS="-O3 -march=prescott -fomit-frame-pointer -pipe -s"

LDFLAGS="-Wl,-O1"

CHOST="i686-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"

 Installed versions:  2.5.1-r2(2.5)(23:21:20 08.07.2007)(berkdb -bootstrap -build doc examples gdbm -ipv6 ncurses -nocxx -nothreads readline sqlite ssl tk -ucs2)

```

2:

```

CFLAGS="-O3 -march=pentium4 -fomit-frame-pointer -pipe"

LDFLAGS="-Wl,-O1"

CHOST="i686-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"

Installed versions:  2.5-r2(2.5)(15:23:49 09.07.2007)(berkdb -bootstrap -build doc gdbm -ipv6 ncurses -nocxx readline sqlite ssl tk -ucs2)

```

3.

```

CHOST="i686-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"

CFLAGS="-O3 -march=k8 -fomit-frame-pointer -pipe"

LDFLAGS="-Wl,-O1"

2.5.1-r2(2.5)(14:29:45 10.07.2007)(berkdb -bootstrap -build doc examples gdbm -ipv6 ncurses -nocxx -nothreads readline sqlite ssl -tk -ucs2)

```

...

А, вот ещё четвёртая машина:

```

CFLAGS="-O2 -march=pentium4 -pipe -fomit-frame-pointer"

LDFLAGS="-Wl,-O1"

CHOST="i686-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"

2.4.4-r4(2.4)(15:48:31 16.05.2007)(berkdb -bootstrap -build doc examples gdbm -ipv6 ncurses -nocxx -nothreads readline ssl -tk -ucs2)

```

там два Xeon-1800, время работы - 50 секунд.

В общем, интересно, откуда такие тормоза :-/

Ядра разнокалиберные, от 2.6.18-gentoo-r3 до 2.6.20-gentoo-r8

----------

## calculator

На 1x xeon 3200 показывает минута.сорок. Другого дистрибутива нет под рукой.

```
CFLAGS="-march=nocona -O2 -pipe"

[ebuild     U ] dev-lang/python-2.4.4-r4 [2.4.3-r4] USE="berkdb gdbm ncurses readline ssl -bootstrap -build -doc -examples% -ipv6 -nocxx -nothreads% -tk -ucs2"
```

  :Wink: Last edited by calculator on Mon Jul 16, 2007 5:56 pm; edited 1 time in total

----------

## Balancer

У знакомого вышло 55 секунд (железо не указано).

Но, чёрт возьми, винда и ubuntu делают это за полторы.

Как??  :Very Happy: 

----------

## Civil

1-ая машина: a64 4000+, 1024MB Ram:

```

real    0m1.415s

user    0m0.014s

sys     0m0.005s

CHOST="i686-pc-linux-gnu"

MAKEOPTS="-j2"

CFLAGS="-O2 -march=k8 -mtune=k8 -ftracer -finline-functions -fomit-frame-pointer -pipe -mfpmath=sse -msse -msse2 -mmmx -m3dnow"

CXXFLAGS="${CFLAGS}"

LDFLAGS="-Wl,-O1"

```

2-ая машина: Athlon XP 1800+ @ 1150MHz (11.5*100 вместо 11.5*133), 1024МБ Рам DDR200 (100*2):

```

real    0m1.211s

user    0m0.158s

sys     0m0.076s

CFLAGS="-O2 -march=athlon-xp -mtune=athlon-xp -msse -m3dnow -mfpmath=sse -finline-functions -ftracer -fomit-frame-pointer -pipe"

CXXFLAGS="${CFLAGS}"

CHOST="i686-pc-linux-gnu"

LDFLAGS="-Wl,-O1"

MAKEOPTS="-j2"

```

На обоих машинах Gentoo 2007.0 (на 1-ой ~x86, на 2-ой x86). Только на первой она после добавления LDFLAG'ов ещё не пересобиралсь.

На обоих машинах:

```
[ebuild   R   ] dev-lang/python-2.4.4-r4  USE="berkdb gdbm ncurses readline ssl -bootstrap -build -doc -examples -ipv6 -nocxx -nothreads -tk -ucs2" 0 kB

```

Помоему всё вполне нормально.

----------

## Laitr Keiows

Можно сравнить тут и там threading.py.

----------

## ba

ну например так...

```
firefly!baz%cat th.py                                                                       <22:33>

#!/usr/bin/env python

import threading

import time

def proc(n):

    time.sleep(1)

for i in xrange(10000):

    threading.Thread(target=proc, name="t"+str(i), args=[i]).start()

0 ~

firefly!baz%time ./th.py                                                                    <22:33>

./th.py  0.00s user 0.01s system 0% cpu 42.380 total

0 ~

firefly!baz%cat th2.py                                                                      <22:34>

#!/usr/bin/env python

import thr

import time

def proc(n):

    time.sleep(1)

for i in xrange(10000):

    thr.Thread(target=proc, name="t"+str(i), args=[i]).start()

0 ~

firefly!baz%time ./th2.py                                                                   <22:34>

./th2.py  2.26s user 0.70s system 80% cpu 3.692 total

0 ~

firefly!baz%diff -u /usr/lib64/python2.4/threading.py thr.py                                <22:34>

--- /usr/lib64/python2.4/threading.py   2007-06-10 17:49:47.000000000 +0400

+++ thr.py      2007-07-14 22:32:13.392405045 +0400

@@ -415,7 +415,7 @@

         _active_limbo_lock.release()

         _start_new_thread(self.__bootstrap, ())

         self.__started = True

-        _sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)

+        #_sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)

     def run(self):

         if self.__target:

1 ~
```

----------

## Balancer

Странно. 0.000001 * 10000 - задержка в 0.01 сек. Или у Питона такой страшный оверхед на выховах функций?

Ну и 3+ секунды (да ещё на amd64) - это всё равно как-то много :-/

----------

## KUV

Хммм...

```
CFLAGS="-march=pentium4 -O2 -pipe"

CHOST="i686-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"
```

```
[ebuild   R   ] dev-lang/python-2.4.4-r4  USE="berkdb gdbm ipv6 ncurses readline ssl -bootstrap -build -doc -examples -nocxx -nothreads -tk -ucs2"
```

```
~/tmp $ ./test.py

Traceback (most recent call last):

  File "./test.py", line 11, in ?

    threading.Thread(target=proc, name="t"+str(i), args=[i]).start()

  File "/usr/lib/python2.4/threading.py", line 416, in start

    _start_new_thread(self.__bootstrap, ())

thread.error: can't start new thread
```

----------

## ba

 *Balancer wrote:*   

> Странно. 0.000001 * 10000 - задержка в 0.01 сек. Или у Питона такой страшный оверхед на выховах функций?

 

вполне возможно что у питона время в слипе квантуется по тикам таймера...

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

----------

## Balancer

 *ba wrote:*   

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

 

Треды реально стартуют. Я вставлял print'ы с отчётами и гонял до 1000 тредов  :Smile: 

Стартуют они и на машинах, где этот код за 1.4 .. 1.5 сек выполняется.

Кстати, посмотрел сейчас - в Windows этот хак тоже есть - _sleep(0.000001)

В Ubuntu смотреть сейчас влом, но подозреваю, что там тоже самое.

Значит, причина кроется в чём-то другом.

...

Да и, повторюсь, даже при выкидывании этой задержки выходит всё равно слишком долгое выполнение.

----------

## Balancer

 *KUV wrote:*   

> Хммм...
> 
> ```
> thread.error: can't start new thread
> ```
> ...

 

Воистину Хммм...

В общем, на трёх машинах проверил - всё ок (отрабатывает, хотя и тормозит), а на четвёртой - не более 382 тредов  :Very Happy: 

Всюду  - Gentoo 2007.0

Одна машина с USE="threads" python-2.4 (всё работает), остальные без "threads", python-2.5 (две работают, одна - нет).

Ничего не понимаю.

----------

## Balancer

Нет, всё даже ещё хитрее! На одной "работающей" машине python-2.5-r2, на другой - python-2.5.1-r2. На "неработающей" - 2.5.1-r2

Флаги всюду одинаковые. Пересобирались все Питоны недавно.

----------

## calculator

 *Quote:*   

> 
> 
> ```
> thread.error: can't start new thread
> ```
> ...

 

Такая же тема на PIII 950/512mb

----------

## viy

Я читал описание к одной софтине (www-servers/skunkweb), в которой отказались от тредов в пользу процессов.

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

В данной проблеме есть вероятность, что все N тредов хотят сделать какую-то операцию одновременно. В результате все ждут, т.к. блок глобальный. Упомянутая задержка в ubuntu/win32 позволяет "разбить" все N тредов на меньшее кол-во групп, минимизировав время ожидания. Сомневаюсь, что там получается N групп по 1 треду, однако эффект налицо.

----------

## Laitr Keiows

 *Balancer wrote:*   

> Флаги всюду одинаковые. Пересобирались все Питоны недавно.

 

Интересно, что скажет diff -r /gentoo/usr/lib/python2.4/ /ubuntu/usr/lib/python2.4/

----------

## d_n_k

real    0m0.485s

user    0m0.012s

sys     0m0.008s

CBUILD="x86_64-pc-linux-gnu"

CFLAGS="-mtune=k8 -O2"

CHOST="x86_64-pc-linux-gnu"

[I--] [  ] dev-lang/python-2.4.4-r4 (2.4)

----------

## anli

На Core 2 Duo E6600 (~amd64) тест из первого сообщения выполняется около 13 секунд. При этом процессор практически не используется (в ksysguard-апплете ничего не заметно).

----------

