Hash/Sharded ActionBlocks
-
21-12-2019 - |
Pergunta
Eu tenho um fluxo constante de determinados itens que eu preciso para processar em paralelo, de forma que eu estou usando TPL Dataflow
.O problema é que os itens que compartilham a mesma chave (semelhante a um Dicionário) deve ser processado em uma ordem FIFO e não estar paralelos um ao outro (que pode ser paralelo a outros itens com valores diferentes).
O trabalho que está sendo feito é muito dependente da CPU com o mínimo assíncrona bloqueios para a minha solução foi criar uma matriz de ActionBlock<T>
s o tamanho do Environment.ProcessorCount
sem paralelismo e pós-lhes de acordo com a chave GetHashCode
o valor.
Criação:
_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);
}
Então, minha pergunta é, isso é a melhor solução para o meu problema?Estou prejudicando o desempenho do/a escalabilidade?Eu estou faltando alguma coisa?
Solução
Eu acho que a sua abordagem é razoável, supondo que você conhece os códigos de hash será distribuído também.
Se você quer ter uma melhor proteção contra maus distribuições, você pode usar o maior número de ActionBlock
s ao limitar a sua total simultaneidade nível usando um único personalizado TaskScheduler
compartilhada por todos os blocos.Você pode encontrar tais programador em ParallelExtensionsExtras ou no MSDN.