Parallel Framework e evitando o compartilhamento falso

Recentemente, eu respondi a uma pergunta sobre a otimização de um provável método paralelizável para gerar toda permutação de números de base arbitrários. Eu postei uma resposta semelhante àImplementação paralela e ruim lista de bloqueio de código, e alguém quase imediatamente apontou isso:

Isso garante que você tenha um compartilhamento falso e provavelmente será muitas vezes mais lento. (crédito paragjvdkamp)

e eles estavam certos, foimorte lento. Dito isto, pesquisei o tópico e encontrei algumasmaterial interessante e sugestões (apenas na revista MSDN arquivada,Assuntos do .NET: compartilhamento falso) para combatê-lo. Se eu entendi direito, quando os threads acessam a memória contígua (por exemplo, a matriz que provavelmente está apoiando essaConcurrentStack), o compartilhamento falso provavelmente ocorre.

Para código abaixo da regra horizontal, umBytes é:

struct Bytes {
  public byte A; public byte B; public byte C; public byte D;
  public byte E; public byte F; public byte G; public byte H;
}

Para meus próprios testes, eu queria obter uma versão paralela dessa execução e ser genuinamente mais rápida, então criei um exemplo simples com base no código original.6 Comolimits[0] foi uma escolha preguiçosa da minha parte - meu computador tem 6 núcleos.

Bloco de rosca única Tempo médio de execução: 10s0059ms

  var data = new List<Bytes>();
  var limits = new byte[] { 6, 16, 16, 16, 32, 8, 8, 8 };

  for (byte a = 0; a < limits[0]; a++)
  for (byte b = 0; b < limits[1]; b++)
  for (byte c = 0; c < limits[2]; c++)
  for (byte d = 0; d < limits[3]; d++)
  for (byte e = 0; e < limits[4]; e++)
  for (byte f = 0; f < limits[5]; f++)
  for (byte g = 0; g < limits[6]; g++)
  for (byte h = 0; h < limits[7]; h++)
    data.Add(new Bytes {
      A = a, B = b, C = c, D = d, 
      E = e, F = f, G = g, H = h
    });

Implementação paralela e ruim Tempo médio de execução: 81s729ms, ~ 8700 contenções

  var data = new ConcurrentStack<Bytes>();
  var limits = new byte[] { 6, 16, 16, 16, 32, 8, 8, 8 };

  Parallel.For(0, limits[0], (a) => {
    for (byte b = 0; b < limits[1]; b++)
    for (byte c = 0; c < limits[2]; c++)
    for (byte d = 0; d < limits[3]; d++)
    for (byte e = 0; e < limits[4]; e++)
    for (byte f = 0; f < limits[5]; f++)
    for (byte g = 0; g < limits[6]; g++)
    for (byte h = 0; h < limits[7]; h++)
      data.Push(new Bytes {
        A = (byte)a,B = b,C = c,D = d,
        E = e,F = f,G = g,H = h
      });
  }); 

Paralelamente, ?? implementação Tempo médio de execução: 5s833ms, 92 contenções

  var data = new ConcurrentStack<List<Bytes>>();
  var limits = new byte[] { 6, 16, 16, 16, 32, 8, 8, 8 };

  Parallel.For (0, limits[0], () => new List<Bytes>(), 
    (a, loop, localList) => { 
      for (byte b = 0; b < limits[1]; b++)
      for (byte c = 0; c < limits[2]; c++)
      for (byte d = 0; d < limits[3]; d++)
      for (byte e = 0; e < limits[4]; e++)
      for (byte f = 0; f < limits[5]; f++)
      for (byte g = 0; g < limits[6]; g++)
      for (byte h = 0; h < limits[7]; h++)
        localList.Add(new Bytes {
          A = (byte)a, B = b, C = c, D = d,
          E = e, F = f, G = g, H = h
        });
      return localList;
  }, x => {
    data.Push(x);
  });

Fico feliz por ter recebido uma implementação mais rápida que a versão single threaded. Eu esperava um resultado próximo de 10s / 6, ou cerca de 1,6 segundos, mas essa é provavelmente uma expectativa ingênua.

Minha pergunta épara a implementação paralelizada que é realmente mais rápida que a versão de thread único, existem otimizações adicionais que podem ser aplicadas à operação? Estou me perguntando sobre otimizações relacionadas à paralelização, não melhorias no algoritmo usado para calcular os valores. Especificamente:

Conheço a otimização para armazenar e preencher como umstruct ao invés debyte[], mas não está relacionado à paralelização (ou é?)Eu sei que um valor desejado pode ser avaliado preguiçosamente com um somador de transporte de ondulação, mas o mesmo que ostruct otimização.

questionAnswers(1)

yourAnswerToTheQuestion