Hash/Sharded ActionBlocks
-
21-12-2019 - |
Pregunta
Tengo un flujo constante de determinados elementos que necesito para procesar en paralelo, así que estoy usando TPL Dataflow
.El problema es que los elementos que comparten la misma clave (similar a un Diccionario) debe ser procesado en un orden FIFO y no ser paralelas entre sí (que puede ser paralelo a otros elementos con valores diferentes).
El trabajo que se realiza es muy CPU con un mínimo de asincrónicas de cerraduras, así que mi solución fue la creación de una matriz de ActionBlock<T>
s el tamaño de Environment.ProcessorCount
sin paralelismo y posteriores a ellos de acuerdo a la clave del GetHashCode
valor.
Creación:
_actionBlocks = new ActionBlock<Item>[Environment.ProcessorCount];
for (int i = 0; i < _actionBlocks.Length; i++)
{
_actionBlocks[i] = new ActionBlock<Item>(_ => ProcessItemAsync(_));
}
Uso:
bool ProcessItem(Key key, Item item)
{
var actionBlock = _actionBlocks[(uint)key.GetHashCode() % _actionBlocks.Length];
return actionBlock.Post(item);
}
Entonces, mi pregunta es, ¿esta es la mejor solución para mi problema?Estoy perjudicando el rendimiento/escalabilidad?Me estoy perdiendo algo?
Solución
Creo que su enfoque es razonable, asumiendo que conoce los códigos hash va a ser distribuidos.
Si quieres tener una mejor protección contra las malas distribuciones usted podría utilizar mayor número de ActionBlock
s limitando su total nivel de simultaneidad mediante el uso de un único personalizado TaskScheduler
compartida por todos los bloques.Usted puede encontrar programador en ParallelExtensionsExtras o en MSDN.