2009-02-17 6 views
6

En una máquina de cuatro núcleos, estoy considerando la paralelización del algoritmo C#/.NET que implica tener múltiples hilos que lean la pequeña matriz int [] al mismo tiempo. Hasta ahora, parece estar funcionando bastante bien, pero no estoy seguro de dónde se especifica que las lecturas concurrentes en una matriz son seguras para subprocesos en .NET. ¿Alguna sugerencia?Acceso de lectura concurrente en una matriz int []: ¿es seguro? ¿Es rápido?

Entonces, ¿me pregunto si este enfoque es realmente eficiente? ¿Hay situaciones en las que es mejor que realmente dupliques los datos de entrada para cada hilo, de modo que no haya ninguna lectura concurrente, y cada arreglo (¿quizás?) Tenga la oportunidad de almacenarse en caché cerca de la CPU de afinidad?

¿Alguna idea sobre las mejores prácticas con respecto a las CPU multinúcleo?

Respuesta

9

En su caso, las lecturas simultáneas de su matriz serán seguras para la ejecución de subprocesos.

En cuanto a la efectividad de sus algoritmos, dependiendo del tamaño de su matriz, si cabe en la caché, entonces puede ver excelentes ganancias de rendimiento, ya que las multinúcleas efectivamente "luchan" por la caché en la CPU. Si están luchando para llenar el caché con la misma información, compartirán el significado de más éxitos de caché y un mejor rendimiento.

Suponiendo que la matriz se inscribe en la memoria caché ...

18

No creo que haya un problema con las lecturas concurrentes. Sin embargo, podría ser problemático si hay escrituras concurrentes.

Los datos inmutables son intrínsecamente seguros para subprocesos.

+0

Estoy totalmente de acuerdo con usted en que los datos inmutables son seguros para subprocesos. A veces, sin embargo, es difícil determinar si los datos no cambiarán. Por ejemplo, una operación de lectura aparente (o digamos 'método de consulta') en un objeto puede causar una escritura interna. Siempre tienes que estar atento a eso. Sin embargo, con arreglos: la lectura de la matriz definitivamente no la cambiará. – Steven

+1

@Steven acepta que no siempre se puede decir si algo es inmutable. Pero creo que tu ejemplo es simplemente un mal diseño. Creo que los datos inmutables (especialmente cuando se comparten) deben diseñarse explícitamente como tales. –

+0

@Marthinho: No tienes idea de cuánto diseño malo presencié en mi operador :-) Me convertí en un desarrollador compulsivo y sospechoso. No confío en nadie, ni siquiera en mí mismo :-) Sin embargo, estoy de acuerdo con todo lo que has dicho aquí. – Steven

4

No hay razón para no leer el contenido de una matriz al mismo tiempo suponiendo que el contenido nunca cambiará. No hay problemas de concurrencia, por lo tanto, no es necesario copiar.

Dudo que haya mucho que pueda hacer para que sea más rápido tampoco.

3

No debería molestarlo. La lectura concurrente no es un problema. Cualquier número de hilos puede leer la misma memoria al mismo tiempo.

2

La seguridad de subprocesos es solo un problema cuando actualiza los datos. Si tiene múltiples hilos concurrentes actualizando la matriz tendrá que envolver las actualizaciones (y las lecturas si las actualizaciones no son atómicas) en un mecanismo de sincronización. Para una estructura de datos de solo lectura, la concurrencia no es un problema.

+0

No necesariamente. En una matriz, no, no es un problema, pero en las colecciones, las lecturas pueden no ser aptas para nada. – Spence

1

El operador de asignación no es seguro para subprocesos.

Esto significa que si sus hilos solo están leyendo la matriz, si la matriz se inicializó al inicio del programa y no cambia, entonces está seguro.

Sin embargo, si existe un escritor que escribe nuevos valores, usted es vulnerable a una condición de carrera.

El problema básico es esto; un lector comienza a leer un número entero. El valor se carga desde la memoria en un registro. En este punto, el lector cambia. El escritor luego actualiza el valor en la memoria. El lector vuelve a intercambiar y actúa sobre el valor que cargó, lo que ya no es correcto.

Esto significa que cosas como if() no funcionan de manera confiable. Por ejemplo,

if(int_array[5] == 10) 
{ 
} 

puede desencadenar cuando el valor en memoria de int_array[5] ya no

10.

Creo en C# es, usted debe tener acceso a los Interlocked*() llamadas a funciones, tales como InterlockedCompareAndSwap(). Esto le permitirá alcanzar fácilmente la seguridad del hilo en este caso.

Cuestiones relacionadas