2012-04-12 19 views
15

Mientras que los actores de Scala son descritos como de peso liviano, los actores de Akka lo son aún más, obviamente hay algo de sobrecarga para usarlos.¿Cuál es la unidad de trabajo más pequeña que es sensata para paralelizar con los actores?

Así que mi pregunta es, ¿cuál es la unidad de trabajo más pequeña que vale la pena el paralelismo con los actores (suponiendo que se puede paralelizar)? ¿Solo vale la pena si hay alguna latencia potencial o hay un lote de cálculos pesados?

Estoy buscando una regla general que pueda aplicar fácilmente en mi trabajo diario.

EDITAR: Las respuestas hasta ahora me han hecho darme cuenta de que lo que me interesa quizás sea realmente el inverso de la pregunta que hice originalmente. Por lo tanto:

Suponiendo que la estructuración de mi programa con los actores es un ajuste muy bueno, y por lo tanto incurre en ninguna sobrecarga adicional de desarrollo (o incluso provoca una sobrecarga menos el desarrollo de una implementación no el actor lo haría), pero las unidades de trabajo se los desempeños son bastante pequeños: ¿hay algún punto en el que usar actores sería perjudicial en términos de rendimiento y debería evitarse?

Respuesta

5

Si utilizar actores no es principalmente una cuestión de la unidad de trabajo, su principal ventaja es hacer que los programas simultáneos sean más fáciles de hacer bien. A cambio de esto, necesitas modelar tu solución de acuerdo con un paradigma diferente.

Por lo tanto, primero debe decidir si usa simultaneidad (lo que puede deberse al rendimiento o la corrección) y luego si se deben usar actores. Este último es en gran medida una cuestión de gusto, aunque con Akka 2.0 necesitaría buenas razones para no hacerlo, ya que obtienes la distribuibilidad (hasta &) esencialmente gratis con muy poca sobrecarga.

Si aún desea decidir al revés, una regla empírica de nuestras pruebas de rendimiento podría ser que la tasa de procesamiento del mensaje objetivo no debe ser superior a unos pocos millones por segundo.

+0

Un punto interesante, y me ha hecho pensar que tal vez hice la pregunta al revés: los actores simplificaron enormemente el diseño de lo que quiero hacer, encajan muy bien en términos de la estructura del programa, sin embargo el Las unidades de trabajo son lo suficientemente pequeñas como para preocuparme por el uso de actores que pueden tener un efecto negativo en el rendimiento. – Russell

+0

Los efectos negativos solo deberían desempeñar un papel si requiere una tasa de mensajes muy alta (como dije: más que unos pocos millones por segundo) O si está dominado por la latencia. Con los actores, es más fácil hacer las cosas en paralelo, lo que significa más cosas por segundo, pero cada cosa tardará un poco más. El intercambio clásico. –

+0

Gracias por sus respuestas, una de esas situaciones desafortunadas donde solo tiene que elegir una para marcar como aceptada. – Russell

4

Mi regla de oro, para el trabajo diario, es que si se tardan milisegundos, entonces vale la pena que se paralelice. Aunque las tasas de transacción son más altas que eso (por lo general, no más de unas pocas decenas de microsegundos de sobrecarga), me gusta mantenerme alejado de los casos dominados por gastos generales. Por supuesto, puede necesitar tomar mucho más tiempo que unos pocos milisegundos en en realidad valdrá la pena paralelizar. Siempre tiene que equilibrar el tiempo empleado escribiendo más código en comparación con el tiempo ahorrado al ejecutarlo.

+0

suena razonable - ¿cuál sería su opinión sobre un programa que era un muy buen ajuste estructural para los actores, pero cuyas unidades de trabajo tomaron menos de milisegundos? – Russell

+0

@Russell - Si el rendimiento es aceptable, use actores. Si no es así, compare un punto de referencia para ver si los actores están tomando la mayoría del tiempo (podría hacerse una idea si envía, por ejemplo, mensajes dobles). –

+0

Gracias por sus respuestas, una de esas situaciones desafortunadas donde solo tiene que elegir una para marcar como aceptada. – Russell

0

Si no se esperan efectos secundarios en las unidades de trabajo, entonces es mejor que tomar una decisión para dividir el trabajo en tiempo de ejecución:

protected T compute() { 
    if (r – l <= T1 || getSurplusQueuedTaskCount() >= T2) 
    return problem.solve(l, r); 
// decompose 
} 

Dónde:

T1 = N/(L * de tiempo de ejecución. getRuntime.availableProcessors())

N - Tamaño del trabajo en unidades

L = 8..16 - factor de carga, configurado manualmente

T2 = 1 ..3 - Max longitud de cola de trabajo después de que todos stealings

Aquí está la presentación con muchos más detalles y cifras:

http://shipilev.net/pub/talks/jeeconf-May2012-forkjoin.pdf

+0

Tenga en cuenta que esa presentación no está en inglés; Aquí hay un enlace de trabajo: http://shipilev.net/pub/talks/jeeconf-May2012-forkjoin.pdf – nezda

Cuestiones relacionadas