GIL e hyperthreading

Francesc Alted falted en pytables.org
Mie Mar 24 20:46:22 CET 2004


A Wednesday 24 March 2004 12:15, Chema Cortes va escriure:
> No comprendo del todo bien el mecanismo del GIL (Global Interpreter 
> Lock) para los procesos multihilo (en CPython). Sé que se hace por 
> conservar el contaje de las referencias a variables, pero no entiendo 
> porqué bloquear todo el intérprete. ¿No sería factible bloquear sólo el 
> acceso a una determinada zona "compartida" en lugar de bloquear todo el 
> intérprete? ¿Realmente es tan complicado eliminar este lock? (Por 
> ejemplo jython no lo tiene).

Pues yo lo intenté comprender una vez, y reconozco que lo tuve que dejar,
porque me perdía.

> Y como "escape", entiendo que va a resultar mejor utilizar "forking" en 
> linux en sistemas multiprocesador pero, ¿qué método sería el más 
> apropiado para intercambiar información entre los procesos sin tener que 
> echar mano de las bases de datos?

Hay varios métodos. Para sistemas multiprocesador con memoria compartida
(SMP), tradicionalmente, uno de los mejores sistemas ha sido el IPC
(Inter-Process Communication), que realmente es una mezcla de diferentes
subsistemas para intercambio de datos entre los diferentes procesadores. 

En Python, se puede acceder a los servicios de compartición de memoria IPC 
mediante el módulo mmap. Sin embargo, creo que hay pequeños problemas de
portabilidad entre plataformas UNIX y Windows debido a las diferentes
implementaciones de IPC que hacen los fabricantes. La sincronización de
procesos la puedes llevar a cabo de múltiples maneras, como por ejemplo, con
los módulos signal (manejadores para eventos asíncronos), Queue (manejadores
de colas LIFO), threading (para usar threads), select (para disparar eventos
al acabar una operación de I/O) o incluso socket, por nombrar sólo unos
cuantos.

Últimamente se está intentando estandarizar una API que agrupe de manera
sensata todo el tema de comunicaciones en sistemas SMP. Se llama OpenMP [0],
pero parece que todavia no hay una implementación para python.

No obstante, existe otra gama de servicios de comunicación más general que
las anteriores: los llamados sistemas de paso de mensajes. Éstos son válidos
para conjuntos completamente generales de procesadores, conocidos como
sistemas de memoria distribuida (DMS), como son por ejemplo un cluster de
PC's o un BeoWulf.

El primero que adquirió fama y se usó con relativa asiduidad se llamaba PVM
(Parallel Virtual Machine). Más tarde apareció otro sistema llamado MPI
(Message Passing Interface) que venia a solucionar ciertos problemas de PVM
y que ha pasado a ser el estándar "de facto" para sistemas DMS. De hecho,
existen implementaciones de MPI que están optimizadas para sistemas de
memoria compartida (SMP), como LAM MPI o MPICH, aparte de unas cuantas
implementaciones propietarias para grandes sistemas SMP, cada una optimizada
para su propio hardware de intercambio de memoria, como las que Sun, SGI, HP
o IBM hacen para sus monstruitos de varias decenas (o centenas) de
procesadores. Una buena implementación de MPI para Python la puedes
encontrar en el paquete Scientific Python [1].

La ventaja que tiene MPI sobre IPC es que se trata de una API estándar y
sobre OpenMP es que se puede aplicar a todos los paradigmas de comunicación
(sea memoria distribuida o compartida), com bastante aprovechameniento de
recursos, es decir, sólo tienes que hacer tu programa una vez, después lo
puedes correr en la configuración que gustes (sea SMP o DMS). La desventaja,
sin embargo, es que es muuuucho más difícil programar con MPI que con IPC (e
incluso que con threads) o OpenMP.

Por otra parte, muchos fabricantes hacen uso de optimizaciones de la capa
TCP/IP para sus plataformas, de modo y manera que te puedes encontrar con la
paradoja de que, si usas sockets 'a pelo', puedes llegar a tener casi las
mismas prestaciones que con servicios IPC o MPI y, aunque ya sabes que la
programación con sockets es la más jodida de todas (incluso que MPI, claro
está), para aplicaciones simples puede ser la más sencilla y portable. Estoy
convencido de que, con las nueva serie de kernels de Linux 2.6.x, las
diferencias de velocidad en la comunicación usando mmap o sockets seran más
bien escasas.

Finalmente, existe una via que no he explorado personalmente, pero que
presiento bastante potente y que se llama el BSP, de sus siglas Bulk
Synchronous Parallel programming [2]. Se trata de un modelo que permite
simplificar la programación de sistemas de memoria distribuida mediante la
división del flujo de ejecución de un programa paralelo en fases de cálculo
y de comunicación. Esto, que parece ser una limitación muy grande comparado
con los sistemas de paso de mensaje (donde cada procesador puede estar en la
fase que quiera en cualquier momento), pues parece que no lo es tanto cuando
te enfrentas a problemas reales (sobretodo con paradigmas SPMD o Simple
Program-Multiple Data)). La gran ventaja de BSP es que eliminas las
situaciones de punto muerto (o como coño se traduzca dead-lock), que, como
sabes, es la gran putada que tienen las aplicaciones paralelas.
 
En palablas de Konrand Kinsen, el autor del paquete Scientific Python así
como de una implementación de BSP para Python, la combinación de Python y
BSP puede cambiar el panorama de relativa poca implantación de aplicaciones
paralelas por parte de la comunidad [3]. Pues eso.

Referencias:

[0] http://www.openmp.org/
[1] http://starship.python.net/~hinsen/ScientificPython/
[2] http://www.bsp-worldwide.org/
[3] http://starship.python.net/~hinsen/ScientificPython/BSP_Tutorial.pdf

Saludos,

-- 
Francesc Alted

------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es