¿Cuellos de botella de subprocesos múltiples ocultos en Jython?

¿Cuáles son algunas de las cosas ocultas comunes que pueden obstaculizar el multihilo / paralelismo en Jython? Tengo algunos códigos paralelos (que utilizan la biblioteca de subprocesos de Python) que no escalan más allá de las CPU de 3-4, y estoy seguro de que no es debido a ninguno de estos escollos obvios:

Básicamente, todo lo que hace el algoritmo es un montón de procesamiento de cadenas, listas y búsquedas de diccionarios y matemáticas. Mi entendimiento es que, a diferencia de CPython, Jython no tiene un GIL.

Acceder a las variables es uno de esos cuellos de botella “ocultos”. Si todos los subprocesos acceden a algunas estructuras de datos compartidas, habrá una sincronización entre los subprocesos.

Jython se esfuerza por lograr la compatibilidad de lenguaje con CPython. Una cosa que el GIL garantiza es que el acceso a variables locales / globales, miembros de objetos, elementos dict (técnicamente locales, globales y miembros de objetos también son elementos dict) o incluso elementos de lista son atómicos. Para evitar sorpresas para los usuarios, Jython utiliza un mapa hash concurrente para implementar los dictados. Esto significa que hay cierta sincronización en curso al acceder a cualquier tipo de elementos dict en Jython. Esta sycnhronización se divide para admitir el acceso al dict de múltiples subprocesos sin bloquearlos, pero si varios subprocesos acceden a la misma variable, van a tener el mismo locking.

La mejor manera de lograr escalabilidad en Jython, y en cualquier otro idioma, es asegurarse de que los datos a los que está accediendo en cada subproceso no se accedan desde otros subprocesos también.

Jython no tiene un GIL, pero es bastante difícil conseguir mucho paralelismo. Si tienes alguna parte que no se puede hacer en paralelo, la Ley de Ahmdahl te muerde:

La aceleración de un progtwig que usa varios procesadores en computación paralela está limitada por el tiempo necesario para la fracción secuencial del progtwig.

Además, incluso si realiza cálculos puramente paralelos, es mordido por otras cosas, como forzar su caché. Además, recuerde que su código se está ejecutando sobre una máquina virtual, por lo que incluso si su código es puramente paralelo, la JVM podría tener alguna coordinación interna que lo frene (la recolección de basura es un candidato obvio).

¿Has probado algún paquete de análisis de rendimiento ? Incluso si no son explícitamente para Jython, apuesto a que sería de alguna ayuda.

Yo probaría YourKit primero si tiene acceso a una licencia.