Pregunta

Estoy trabajando en un proyecto donde necesitamos más rendimiento.Con el tiempo, hemos seguido evolucionando el diseño para que funcione más en paralelo (tanto en subprocesos como distribuido).Luego, el último paso fue trasladar parte de él a una nueva máquina con 16 núcleos.Estoy descubriendo que necesitamos repensar cómo hacemos las cosas para escalar a tantos núcleos en un modelo de memoria compartida.Por ejemplo, el asignador de memoria estándar no es lo suficientemente bueno.

¿Qué recursos recomendaría la gente?

Hasta ahora he encontrado la columna de Sutter, Dr.Dobbs será un buen comienzo.Acabo de recibir El arte de la programación multiprocesador y el libro de O'Reilly sobre Intel Threading Building Blocks

¿Fue útil?

Solución

Un par de libros más que serán útiles son:

Además, considere confiar menos en compartir el estado entre procesos concurrentes.Escalará mucho, mucho mejor si puede evitarlo porque podrá dividir unidades de trabajo independientes sin tener que realizar tanta sincronización entre ellas.

Incluso si necesita compartir algún estado, vea si puede dividir el estado compartido del procesamiento real.Esto le permitirá realizar la mayor parte del procesamiento en paralelo, independientemente de la integración de las unidades de trabajo completadas al estado compartido.Obviamente, esto no funciona si hay dependencias entre unidades de trabajo, pero vale la pena investigar en lugar de simplemente asumir que el estado siempre será compartido.

Otros consejos

Quizás quieras echar un vistazo Herramientas de rendimiento de Google.Han lanzado su versión de malloc que utilizan para aplicaciones multiproceso.También incluye un buen conjunto de herramientas de creación de perfiles.

A Jeffrey Richter le gusta mucho enhebrar.Tiene algunos capítulos sobre enhebrado en sus libros y consulte su blog:

http://www.wintellect.com/cs/blogs/jeffreyr/default.aspx.

Como diría Monty Python "y ahora algo completamente diferente", podría probar un lenguaje/entorno que no utilice subprocesos, sino procesos y mensajes (sin estado compartido).Uno de los más maduros es erlang (y este excelente y divertido libro: http://www.pragprog.com/titles/jaerlang/programming-erlang).Puede que no sea exactamente relevante para sus circunstancias, pero aún así puede aprender muchas ideas que podrá aplicar en otras herramientas.

Para otros entornos:

.Net tiene F# (para aprender programación funcional).JVM tiene Scala (que tiene actores, muy parecidos a Erlang, y es un lenguaje híbrido funcional).También existe el marco "fork join" de Doug Lea para Java que hace gran parte del trabajo duro por usted.

El asignador en FreeBSD recibió recientemente una actualización para FreeBSD 7.el nuevo se llama jemaloc y aparentemente es mucho más escalable con respecto a múltiples subprocesos.

No mencionaste qué plataforma estás utilizando, por lo que quizás este asignador esté disponible para ti.(Yo creo Firefox 3 usa jemalloc, incluso en ventanas.Entonces los puertos deben existir en alguna parte).

Echa un vistazo a Acumular si está asignando mucha memoria.

enrolla el tuyo Lista libre de bloqueo.Un buen recurso está aquí: está en C# pero las ideas son portátiles.Una vez que te acostumbras a cómo funcionan, empiezas a ver otros lugares donde se pueden utilizar y no sólo en listas.

Tendré que revisar Hoard, Google Perftools y jemalloc en algún momento.Por ahora estamos usando scalable_malloc de Intel Threading Building Blocks y funciona bastante bien.

Para bien o para mal, estamos usando C++ en Windows, aunque gran parte de nuestro código se compilará perfectamente con gcc.A menos que haya una razón convincente para pasar a Redhat (la principal distribución de Linux que usamos), dudo que valga la pena el dolor de cabeza y los problemas políticos para cambiar.

Me encantaría usar Erlang, pero hay muchas cosas aquí para rehacerlo ahora.Si pensamos en los requisitos relacionados con el desarrollo de Erlang en un entorno de telecomunicaciones, son muy similares a los de nuestro mundo (comercio electrónico).El libro de Armstrong está en mi pila para leer :)

En mis pruebas para escalar de 4 núcleos a 16 núcleos, aprendí a apreciar el costo de cualquier bloqueo/contención en la parte paralela del código.Afortunadamente, tenemos una gran parte que escala con los datos, pero ni siquiera eso funcionó al principio debido a un bloqueo adicional y al asignador de memoria.

Mantengo un blog de enlaces de concurrencia que puede ser de interés continuo:

http://concurrency.tumblr.com

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top