¿Cómo puedo mejorar el rendimiento del recolector de basura de .NET 4.0 en código altamente concurrente?

Estoy usando la biblioteca paralela de tareas de .NET Framework 4 (específicamenteParallel.For yParallel.ForEach) sin embargo, estoy obteniendo aceleraciones extremadamente mediocres cuando se paralelizan algunas tareas que parecen ser fácilmente paralelizadas en una máquina de doble núcleo.

Al perfilar el sistema, parece que hay mucha sincronización de subprocesos debido al recolector de basura. Estoy haciendo una gran cantidad de asignación de objetos, por lo que me pregunto cómo puedo mejorar la concurrencia mientras minimizo una reescritura de mi código.

Por ejemplo, hay algunas técnicas que pueden ser útiles en esta situación:

¿Debo tratar de administrar el GC manualmente?Debería estar usandoDispose?¿Debería fijar objetos?¿Debo estar haciendo otros trucos de código inseguro?

POSDATA:

El problema no es que el GC se ejecute con demasiada frecuencia, es que el GC evita que el código concurrente se ejecute en paralelo de manera eficiente. Tampoco considero que "asignar menos objetos" sea una respuesta aceptable. Eso requiere reescribir demasiado código para evitar un recolector de basura mal paralelo.

Ya encontré un truco que ayudó al rendimiento general (usando gcServer) pero no ayudó al rendimiento concurrente. En otras palabrasParallel.For fue solo un 20% más rápido que un ciclo For serial, en una tarea vergonzosamente paralela.

POST-POSTSCRIPT:

Bien, permítanme explicar más, tengo un programa bastante grande y complejo: un intérprete optimizador. Es lo suficientemente rápido, pero quiero que su rendimiento cuando se den tareas paralelas (operaciones primitivas integradas en mi lenguaje) se escalen bien a medida que haya más núcleos disponibles. Asigno muchos objetos pequeños durante las evaluaciones. Todo el diseño del intérprete se basa en todos los valores derivados de un único objeto base polimórfico. Esto funciona muy bien en una aplicación de un solo subproceso, pero cuando intentamos aplicar la Biblioteca de tareas paralelas a evaluaciones paralelas no hay ninguna ventaja.

Después de mucha investigación sobre por qué la Biblioteca de tareas paralelas no distribuía adecuadamente el trabajo entre los núcleos para estas tareas, parece que el culpable es el GC. Aparentemente, el GC parece actuar como un cuello de botella porque hace algo de sincronización detrás del escenario que no entiendo.

Lo que necesito saber es: ¿qué está haciendo exactamente el GC que puede hacer que el código altamente concurrente funcione mal cuando realiza muchas asignaciones y cómo podemos solucionarlo?otro que sóloasignar menos objetos. Ese enfoque ya se me ocurrió y requeriría una reescritura significativa de mucho código.

Respuestas a la pregunta(8)

Su respuesta a la pregunta