Este artigo foi traduzido por máquina.

Computação paralela

Processamento de dados: paralelismo e desempenho

Johnson M. Hart

Baixe o código de exemplo

Coletas de dados de processamento é uma tarefa fundamental de computação e uma série de problemas práticos é inerentemente paralela, potencialmente permitindo que o melhor desempenho e a taxa de transferência em sistemas com vários núcleos. Irá comparar vários baseados em Windows métodos distintos para solucionar problemas com um alto grau de paralelismo de dados.

O parâmetro de comparação que usarei para essa comparação é um problema de pesquisa (“ Geonames ”) do capítulo 9 do livro ’ Troy Magennis “ LINQ to Objects usando c# 4. 0 ” (Addison-Wesley, 2010). As soluções alternativas são:

  • Paralela PLINQ (Language Integrated Query) e o c# 4. 0, com e sem aprimoramentos para o código original.
  • Código nativo do Windows usando C, a API do Windows, threads e arquivos mapeados na memória.
  • Windows c# / Microsoft .NET Framework com vários segmentos de código.

O código-fonte para todas as soluções está disponível no meu site da Web (jmhartsoftware.com ). Outras técnicas de paralelismo, tais como o Windows Task Parallel TPL (biblioteca), não são examinadas diretamente, apesar do PLINQ é colocada em camadas sobre a TPL.

Comparar e avaliar soluções alternativas

Os critérios de avaliação de solução, por ordem de importância, são:

  • Total de desempenho em termos de tempo decorrido para concluir a tarefa.
  • Escalabilidade com o grau de paralelismo (número de tarefas), tamanho da coleção contagem e os dados do núcleo.
  • O código de simplicidade, elegância, facilidade de manutenção e de fatores intangíveis semelhantes.

Resumo de resultados

Este artigo mostrará que para resolver um problema de pesquisa representativo de benchmark:

  • Você pode explorar com sucesso sistemas multinucleados de 64 bits para melhorar o desempenho em muitos problemas de processamento de dados e o PLINQ pode fazer parte da solução.
  • Desempenho de PLINQ dos concorrentes e dimensionável requer que objetos da coleção de dados indexados;não é suficiente que suportam a interface IEnumerable.
  • O c# .net e soluções de código nativo são mais rápidas.
  • A solução original do PLINQ é mais lenta por um fator de aproximadamente 10, e não expandir além das duas tarefas, ao passo que as outras soluções de escala bem até seis tarefas com seis núcleos (máximo testado). No entanto, os aprimoramentos de código melhoram significativamente a solução original.
  • O código PLINQ é a mais simples e mais elegante em todos os aspectos de como o LINQ oferece um recurso de consulta declarativa para dados residentes na memória e externas. O código nativo é ungainly e o c# é consideravelmente melhor do que o código do .NET — mas não tão simples quanto — o código do PLINQ.
  • Escala de todos os métodos bem com o arquivo de tamanho os limites da memória física de sistema de teste.

O problema de avaliação de desempenho: Geonames

A idéia desse artigo veio do capítulo 9 do livro LINQ ’ Magennis, que demonstra o PLINQ, procurando um banco de dados geográfico que contenha mais de milhões de 7,25 nomes de locais em um arquivo de 825 MB (ou seja, mais de um local para cada 1000 pessoas). Cada nome de local é representado por um registro de linha de texto (comprimento variável) UTF-8 (en.wikipedia.org/wiki/UTF-8 ) com até 15 colunas de dados separados por tabulações. Observação: A codificação UTF-8 garante que uma guia (0x9) ou valor (0xA) de alimentação de linha não ocorrerão como parte de uma seqüência de bytes múltiplosIsso é essencial para várias implementações.

Programa de Geonames ’ Magennis implementa uma consulta codificados para identificar todos os locais com uma elevação (coluna 15) mais de 8000 metros, exibindo o nome da localização, país e elevação, classificados pela diminuição de elevação. Caso você esteja se perguntando, existem 16 locais e MT Everest é a mais alta em 8,848 metros.

Os relatórios de Magennis tempos decorridos de 22,3 segundos (um principal) e segundos 14,1 (dois núcleos). Experiência anterior (por exemplo, consulte meu artigo “ Windows paralelismo, pesquisa rápida de arquivos e processamento especulativo ” em informit.com/articles/article.aspx?p=1606242 de ) mostra que os arquivos desse tamanho podem ser processados em alguns segundos e desempenho dimensiona bem com a contagem de núcleo. Portanto, decidi tentar replicar essa experiência e também tentar aperfeiçoar o código do PLINQ ’ Magennis para melhorar o desempenho. Os aprimoramentos do PLINQ iniciais quase dobrou o desempenho, mas não melhoram a escalabilidade;outros aperfeiçoamentos, entretanto, produzir desempenho quase tão bons quanto nativo e c# códigos com vários segmentos.

Esse parâmetro de comparação é interessante por vários motivos:

  • O assunto (locais geográficos e atributos) é inerentemente interessante e facilitar a generalize a consulta.
  • Não há um alto grau de paralelismo de dados;em princípio, todos os registros podem ser processado ao mesmo tempo.
  • O tamanho do arquivo é modesto pelos padrões de hoje, mas é muito fácil de testar com arquivos maiores simplesmente concatenando Geonames allCountries.txt arquivo a mesmo várias vezes.
  • O processamento não está sem monitoração de estado;é necessário determinar os limites de linha e o campo para o arquivo da partição e as linhas precisam ser processadas para identificar os campos 
individual.

Uma pressuposição: Presuma que o número de registros identificados (nesse exemplo, localizações superiores a 8000 metros) é pequeno, para que, classificação e exibição de tempo são mínimas em relação do geral tempo de processamento, o que envolve o exame de cada byte.

Outra pressuposição: Os resultados de desempenho representam o tempo necessário para processar os conjuntos de dados residentes na memória, como, por exemplo, dados produzidos por uma etapa anterior do programa. O programa de benchmark lê um arquivo, mas o teste de programas são executados várias vezes para garantir que o arquivo está residente na memória. No entanto, menciono será o tempo necessário para carregar o arquivo inicialmente e, neste momento é aproximadamente o mesmo para todas as soluções.

Comparação de desempenho

O primeiro sistema de teste é um sistema de área de trabalho de seis principais que executam o Windows 7 (AMD Phenom II, 2,80 GHz, 4 GB de RAM). Posteriormente, apresentarei os resultados de três outros sistemas com hiperthreading ou HT (en.wikipedia.org/wiki/Hyper-threading ) e contagens de núcleo diferente.

A Figura 1 mostra os resultados para seis diferentes soluções Geonames, com o tempo decorrido (segundos) como uma função de “ grau de paralelização ” ou solte (o número de tarefas paralelas, que pode ser definido como maior do que o número de processadores);o sistema de teste possui seis núcleos, mas as implementações de controlam o solte. Seis tarefas são ideais;usando mais de seis tarefas degradação de desempenho. Todos os testes de usam o arquivo de dados de allCountries.txt Geonames 825 MB original.

image: Geonames Performance as a Function of Degree of Parallelism

Figura 1 do desempenho Geonames como uma função do grau de paralelismo

As implementações são (mais explicações seguirá):

  1. Geonames Original. Esta é a solução PLINQ original ’ Magennis. O desempenho não é dos concorrentes e não dimensionar com o número de processadores.
  2. Auxiliar de Geonames. Esta é uma versão aprimorada para desempenho de do Geonames Original.
  3. Geonames MMChar. Essa foi uma tentativa sem êxito para melhorar o do Auxiliar de Geonames com uma classe de arquivo mapeado para memória semelhante àquele utilizado no Threads Geonames . Observação: O mapeamento de memória permite que um arquivo a ser referenciado como se fosse na memória sem explícitas as operações de e/S e ele pode fornecer benefícios de desempenho.
  4. Geonames MMByte. Essa solução modifica do MMChar para processar os bytes individuais do arquivo de entrada, ao passo que as soluções anteriores de três caracteres UTF-8 de converter para Unicode (com 2 bytes cada). O desempenho é a melhor as quatro primeiras soluções e é mais do que dobrar do Geonames Original de .
  5. Threads de Geonames não usa o PLINQ. Esta é a linguagem c# / implementação no .net usando threads e um arquivo mapeado para memória. O desempenho é mais rápido do que o (o item seguinte), índice e sobre o mesmo que o de nativo. Esta solução e Nativo Geonames fornecem melhor escalabilidade de paralelismo.
  6. Índice Geonames. Essa solução PLINQ pré-processa o arquivo de dados (necessitando de cerca de nove segundos) para criar uma lista de residente em memória < byte [] >objeto para o processamento do PLINQ subseqüente. O custo de pré-processamento pode ser amortizado ao longo de várias consultas, fornecendo o desempenho é apenas um pouco mais lento do que o Nativo Geonames e Threads Geonames .
  7. Geonames nativo (não mostrada no do Figura 1) não usa o PLINQ. Esta é a implementação da C API do Windows usando um arquivo de memória mapeada como no capítulo 10 do meu livro, “ Windows System Programming ” (Addison-Wesley, 2010) e de segmentos. Otimização do compilador completo é essencial para esses resultados;a otimização de padrão fornece apenas cerca de metade de desempenho.

Todas as implementações são versões de 64 bits. versões de 32 bits funcionam na maioria dos casos, mas eles não para arquivos maiores (consulte do Figura 2). A Figura 2 mostra o desempenho usando solte 4 e os arquivos maiores.

image: Geonames Performance as a Function of File Size

A Figura 2 do desempenho Geonames como uma função do tamanho do arquivo

Nesse caso, o sistema de teste possui quatro núcleos (AMD Phenom Quad-Core, 2,40 GHz, 8 GB de RAM). Os arquivos grandes foram criados pela concatenação de várias cópias do arquivo original. A Figura 2 mostra apenas as três mais rápidas soluções, incluindo o do Índice Geonames — a solução mais rápida do PLINQ (sem contar arquivos de pré-processamento) — e o desempenho melhora com o tamanho do arquivo até os limites de memória física.

Agora eu vai descrever implementações de dois a sete e discutir as técnicas PLINQ em mais detalhes. Que, falarei sobre os resultados a seguir em outros sistemas de teste e resumir os resultados.

Soluções aprimorado do PLINQ: Auxiliar de Geonames

A Figura 3 mostra o código do Original GeonamesAuxiliar Geonames com minhas alterações (em negrito).

A Figura 3 do Auxiliar de Geonames com as alterações realçadas para o código original do PLINQ

class Program
{
  static void Main(string[] args)
  {
    const int nameColumn = 1;
    const int countryColumn = 8;
    const int elevationColumn = 15;

    String inFile = "Data/AllCountries.txt";
    if (args.Length >= 1) inFile = args[0];
        
    int degreeOfParallelism = 1;
    if (args.Length >= 2) degreeOfParallelism = int.Parse(args[1]);
    Console.WriteLine("Geographical data file: {0}.
Degree of Parallelism: {1}.", inFile, degreeOfParallelism);

    var lines = File.ReadLines(Path.Combine(
      Environment.CurrentDirectory, inFile));

    var q = from line in 
      lines.AsParallel().WithDegreeOfParallelism(degreeOfParallelism)
        let elevation = 
          Helper.ExtractIntegerField(line, elevationColumn)
        where elevation > 8000 // elevation in meters
        orderby elevation descending
        select new
        {
          elevation = elevation,
          thisLine = line
         };

    foreach (var x in q)
    {
      if (x != null)
      {
        String[] fields = x.thisLine.Split(new char[] { '\t' });
        Console.WriteLine("{0} ({1}m) - located in {2}",
          fields[nameColumn], fields[elevationColumn], 
          fields[countryColumn]);
      }
    }
  }
}

Como muitos leitores talvez não estejam familiarizados com o PLINQ e c# 4. 0, fornecerá alguns comentários sobre o Figura 3 , incluindo descrições dos aprimoramentos:

  • As linhas 9 a 14 permitem que o usuário especifique o nome do arquivo de entrada e o grau de paralelismo (o número máximo de tarefas simultâneas) na linha de comando;Esses valores estão codificados no original.
  • As linhas 16 e 17 começa a ler as linhas do arquivo de forma assíncrona e implicitamente digite linhas como uma matriz de cadeia de caracteres c#. Os valores de linhas não são usados até 19-27 de linhas. Outras soluções, como do Geonames MMByte, usam uma classe diferente com seu próprio método ReadLines e essas linhas de código são apenas as linhas que precisam ser alteradas.
  • 19-27 As linhas são o código do LINQ juntamente com a extensão PLINQ AsParallel. O código é semelhante ao SQL e variável “ q ” é digitado implicitamente como uma matriz de objetos que consiste em um número inteiro de elevação e uma seqüência de caracteres. Observe que o PLINQ executa todo o trabalho de gerenciamento de threads;o método AsParallel é tudo o que é necessária para ativar o código serial do LINQ para PLINQ código.
  • Linha 20. Figura 4 mostra o método Helper.ExtractIntegerField. O programa original usa o método String.Split de maneira semelhante à usada para exibir os resultados na linha de 33 ( do Figura 3). Esta é a chave para melhorar o desempenho de Auxiliar Geonames do Geonames Original, comparado com, pois ele não é mais necessário alocar objetos String para todos os campos em cada linha.

Figura 4 de classe do auxiliar Geonames e o método de ExtractIntegerField

class Helper
{
  public static int ExtractIntegerField(String line, int fieldNumber)
  {
    int value = 0, iField = 0;
    byte digit;

    // Skip to the specified field number and extract the decimal value.
foreach (char ch in line)
    {
      if (ch == '\t') { iField++; if (iField > fieldNumber) break; }
      else
      {
        if (iField == fieldNumber)
        {
          digit = (byte)(ch - 0x30);  // 0x30 is the character '0'
          if (digit >= 0 && digit <= 9) 
            { value = 10 * value + digit; }
          else // Character not in [0-9].
Reset the value and quit.
{ value = 0; break; }
        }
      }
    }
    return value;
  }
}

Observe que o método AsParallel usado na linha 19 pode ser usado com qualquer objeto IEnumerable. Como mencionei anteriormente, do Figura 4 mostra a classe do auxiliar do método ExtractIntegerField. Ele simplesmente extrai e avalia o campo especificado (elevação neste caso), evitando a métodos de biblioteca de desempenho. A Figura 1 mostra que esse aprimoramento dobra o desempenho com solte 1.

Geonames MMChar e Geonames MMByte

Geonames MMChar representa uma tentativa sem êxito para melhorar o desempenho, o arquivo de entrada, usando uma classe personalizada, FileMmChar de mapeamento de memória. Geonames MMByte, entretanto, produzir benefícios significativos, como os bytes de arquivo de entrada não são expandidos para Unicode.

MMChar requer uma nova classe, FileMmChar, que suporta o IEnumerable <String>interface. A classe FileMmByte é semelhante e lida com objetos de byte [], em vez de objetos de cadeia de caracteres. A alteração somente significativa de código é Figura 3 , linhas 16 e 17, que agora são:

var lines = FileMmByte.ReadLines(Path.Combine(
    Environment.CurrentDirectory, inFile));

O código para

public static IEnumerable<byte[]> ReadLines(String path)

que suporte o IEnumerable < byte [] >interface de FileMmByte constrói um objeto FileMmByte e um IEnumerator < byte [] >objeto examinará o arquivo mapeado para as linhas individuais.

Observe que as classes FileMmChar e FileMmByte “ inseguros ” porque eles criar e usam ponteiros para acessar os arquivos e usar a linguagem c# / nativo interoperabilidade de código. O uso de ponteiro, entretanto, é isolado em um assembly separado, e o código usa matrizes em vez de desreferência de ponteiro. A classe MemoryMappedFile do .NET Framework 4 não ajuda, porque é necessário usar as funções de assessor para mover dados de memória mapeada.

Geonames nativo

Geonames nativo explora a API do Windows, threads e mapeamento de memória do arquivo. Os padrões de código básico são descritos no capítulo 10 do “ Programming Windows System ”. O programa deve gerenciar as conversações diretamente e cuidadosamente também deve mapear o arquivo de memória. O desempenho é muito melhor do que todas as implementações do PLINQ, exceto o do Índice Geonames.

No entanto, há uma distinção importante entre o problema Geonames e uma pesquisa de arquivos simples, sem monitoração de estado ou de transformação. O desafio é determinar o método correto de partição os dados de entrada para atribuir a partições diferentes para diferentes tarefas. Não há nenhuma maneira óbvia de determinar os limites de linha sem examinar todo o arquivo, portanto, não é possível atribuir uma partição de tamanho fixo para cada tarefa. No entanto, a solução é simples quando ilustrado com solte 4:

  • Dividir o arquivo de entrada em quatro partições iguais, com a partição local comunicada a cada thread como parte do argumento da função no segmento de início.
  • Cada thread de ter, em seguida, processar todas as linhas (registros) que Iniciar na partição. Isso significa que um thread provavelmente irá examinar para a próxima partição a fim de concluir o processamento da última linha que começa na partição.

Threads de Geonames

Threads de Geonames usa a mesma lógica como Nativo Geonames ;Na verdade, alguns códigos é o mesmo ou quase a mesma. No entanto, as expressões lambda, os métodos de extensão, contêineres e outros c# / recursos .net simplificam bastante a codificação.

Como com MMByte de e MMChar , o mapeamento de memória do arquivo exige “ inseguros ” classes e o c# / nativo interoperabilidade de código para usar ponteiros para a memória mapeada. O esforço valer a pena, entretanto, é porque o Threads Geonames desempenho é igual a desempenho de Geonames nativo com muito mais simples do código.

Índice Geonames

Os resultados do PLINQ ( do original, do auxiliar, MMChar e do MMByte) são decepcionantes comparado aos resultados de Threads do .net e nativos de . Existe uma maneira de explorar a simplicidade e elegância do PLINQ, sem sacrificar o desempenho?

Embora seja impossível determinar exatamente como o PLINQ processa a consulta (linhas 16 27 do Figura 3), é provável que o PLINQ não tem um bom como particionar as linhas de entrada para tarefas separadas de processamento paralelo. Como uma hipótese de trabalho, assumem que o particionamento pode ser a causa do problema de desempenho do PLINQ.

No catálogo ’ Magennis (pp. 276 279), a matriz de cadeia de caracteres de linhas oferece suporte o IEnumerable <String>(Consulte também livro da Sharp John, “ Microsoft Visual C# 2010 Step by Step ” [Microsoft Press, 2010], capítulo 19) da interface. No entanto, as linhas não está indexado, portanto, provavelmente, o PLINQ utiliza “ divida particionamento ”. Além disso, os métodos IEnumerator.MoveNext para as classes FileMmChar e FileMmByte são lentos porque eles precisam para examinar todos os caracteres até a próxima linha nova está localizada.

O que aconteceria se a matriz de cadeia de caracteres de linhas foi indexada? Nós pode melhorar o desempenho do PLINQ, especialmente quando suplementado por memória o arquivo de entrada de mapeamento? Índice Geonames mostra essa técnica melhorar o desempenho, gerando resultados semelhantes para código nativo. Em geral, no entanto, o local de um custo antecipado necessário para mover as linhas a uma lista na memória ou uma matriz, que é indexada (o custo, em seguida, pode ser amortizado ao longo de várias consultas), ou o arquivo ou outra fonte de dados já está indexado, talvez durante a geração de uma etapa anterior do programa, eliminando a pré-processamento custo.

A operação de indexação inicial é simples;acesso apenas a cada linha, uma vez e, em seguida, adicione a linha a uma lista. Use o objeto da lista em linhas 16 e 17, conforme ilustrado no do Figura 3 e este trecho de código que mostra os pré-processamento:

// Preprocess the file to create a list of byte[] lines
List<byte[]> lineListByte = new List<byte[]>();
var lines = 
    FileMmByte.ReadLines(Path.Combine(Environment.CurrentDirectory, inFile));
// ...
Multiple queries can use lineListByte
// ....
foreach (byte[] line in lines) { lineListByte.Add(line); }
// ....
var q = from line in lineListByte.AsParallel().
WithDegreeOfParallelism(degreeOfParallelism)

Observe que é um pouco mais eficiente para processar os dados posteriormente, convertendo a lista em uma matriz, embora isso aumenta o tempo de pré-processamento.

Um aumento de desempenho final

Índice Geonames desempenho pode ser aprimorado ainda mais indexando campos em cada linha para que o método ExtractIntegerField não precise examinar todos os caracteres em uma linha de saída para o campo especificado.

A implementação, do Geonames IndexFields, modifica o método ReadLines para que uma linha retornada é um objeto que contém uma matriz de bytes [] e de uma matriz de [] uint contendo os locais de cada campo. Isso resulta em sobre uma melhoria de desempenho de 33 por cento, sobre o do Índice Geonames e traz o desempenho bem perto para o nativo e c# / soluções .net. (Geonames IndexFields está incluído no download do código.) Além disso, agora é mais fácil construir consultas mais gerais como os campos individuais estão prontamente disponíveis.

Limitações

Exigem que as soluções eficientes para todos os dados residentes na memória e as vantagens de desempenho não estendem para coletas de dados muito grandes. “ Grande ” nesse caso indica os tamanhos de dados dessa abordagem, o tamanho da memória física do sistema. No exemplo de Geonames, o arquivo 3,302 MB (quatro cópias do arquivo original) pôde ser processado no sistema de teste de 8 GB. Um teste com oito cópias concatenados do arquivo, no entanto, foi muito lento com todas as soluções.

Como mencionado anteriormente, o desempenho também é melhor quando os arquivos de dados são “ reais, ” no sentido de que eles já foram acessados recentemente e provavelmente estarão na memória. A paginação no arquivo de dados durante a execução inicial pode demorar 10 ou mais segundos e é comparável a operação de indexação no trecho de código anterior.

Em resumo, os resultados deste artigo se aplicam a estruturas de dados residentes na memória e tamanhos de memória e os preços atuais permite que os objetos de dados significativos, como um arquivo de nomes local 7,25 milhões, seja residente na memória.

Resultados do teste de sistema adicionais

A Figura 5 mostra os resultados do teste em um sistema adicional (Intel i7 860, 2 GHz, quatro núcleos, oito threads, Windows 7, 4 GB de RAM). O processador suporta hyperthreading, para que o testadas solte os valores são 1, 2 etc., 8. A Figura 1 baseia-se em um sistema de teste com seis núcleos AMD;Este sistema não dá suporte a hipersegmentação.

image: Intel i7 860, 2.80GHz, Four Cores, Eight Threads, Windows 7, 4GB RAM

A Figura 5 do Intel i7 860, 2,80 GHz, 4 núcleos, oito threads, o Windows 7, 4 GB de RAM

Duas configurações adicionais de teste gerou resultados semelhantes (e os dados completos estão disponíveis em meu site da Web):

  • Intel i7 720, 1 GHz, quatro núcleos, oito threads, Windows 7, 8 GB de RAM
  • Intel i3 530, 2,93 GHz, dois núcleos, quatro segmentos, Windows XP64, 4 GB de RAM

Características de desempenho interessantes:

  • Threads de Geonames consistentemente fornece o melhor desempenho, juntamente com o Nativo Geonames .
  • Índice Geonames é a solução mais rápida do PLINQ, abordar o desempenho do Geonames Threads . Observação: GeonamesIndexFields é ligeiramente mais rápido, mas não será mostrado emdo Figura 5.
  • Diferente de do Índice Geonames, todas as soluções do PLINQ dimensionar negativamente com o solte para solte maior do que dois;ou seja, o desempenho diminui à medida que o número de paralelo aumentos de tarefas. Neste exemplo, o PLINQ produz um bom desempenho, somente quando usada com objetos indexados.
  • A contribuição de desempenho do hyper-threading é marginal. Portanto, o Threads Geonames e desempenho do Índice Geonames não aumenta significativamente para solte maior do que quatro. Essa capacidade de expansão HT ruim pode ser uma conseqüência de agendar dois threads nos processadores lógicos no núcleo do mesmo, em vez de garantir que ele é executado em núcleos diferentes sempre que possível. No entanto, essa explicação não parece ser plausível como e de marca. Russinovich, David a. Solomon e Alex Ionescu dizem que os processadores físicos sejam programados antes de processadores lógicos no p. 40 do seu livro, “ Windows Internals, edição quinto ” (Microsoft Press, 2009). Os sistemas AMD sem HT ( do Figura 1) forneceu cerca de três a quatro vezes o desempenho com solte maior do que quatro, em comparação com o seqüencial solte uma resultados de de threads, nativo de e de índice de . A Figura 1 mostra que o melhor desempenho ocorre quando o solte é a mesma que a contagem de núcleo, em que o desempenho de vários segmentos é 4. 2 vezes o solte um desempenho.

Resumo de resultados

O PLINQ fornece um excelente modelo para o processamento de estruturas de dados na memória e é possível melhorar o desempenho do código existente com algumas alterações simples (por exemplo, do auxiliar) ou com técnicas mais avançadas, como foi mostrado com do MMByte. No entanto, nenhum dos aperfeiçoamentos simples fornece desempenho próximo do nativo ou multithreaded c# / código .net. Além disso, o aprimoramento não dimensionar com a contagem de núcleo e solte.

O PLINQ pode vir de fechamento para o nativo e c# / desempenho do código .net, mas requer o uso de objetos de dados indexados.

Usando o código e dados

Todo o código está disponível em meu site da Web (jmhartsoftware.com/SequentialFileProcessingSupport.html de ), seguindo estas instruções:

  • Vá para a página para baixar um arquivo ZIP contendo o código do PLINQ e código de Geonames Threads. Todas as variações do PLINQ estão no projeto GeonamesPLINQ (Visual Studio 2010;O Visual Studio 2010 Express é suficiente). GeonamesThreads está no projeto GeonamesThreads Visual Studio 2010. Os projetos estão configurados para compilações de versão de 64 bits. Além disso, o arquivo ZIP contém uma planilha com os dados de desempenho bruto usados em figuras 1, 2 e 5. Um comentário de “ uso ” simples no topo do arquivo explica a opção de linha de comando para selecionar o arquivo de entrada, solte e implementação.
  • Vá para a programação de sistema do Windows página de suporte (jmhartsoftware.com/comments_updates.html ) para baixar o código de Geonames nativo e os projetos (um arquivo ZIP), onde você encontrará o projeto Geonames. Um arquivo Readme. txt explica a estrutura.
  • Baixe o banco de dados GeoNames a partir de download.geonames.org/export/dump/allCountries.zip .

Perguntas sobre desconhecido

Este artigo em comparação com o desempenho de várias técnicas alternativas para solucionar o problema do mesmo. A abordagem foi para usar as interfaces padrão como eles estão descritos e assume um modelo de memória compartilhada simples para os processadores e segmentos. No entanto, não houve nenhum esforço significativo para investigar profundamente no implementações subjacentes ou recursos específicos de computadores de teste, e várias perguntas poderiam ser investigadas no futuro. Eis alguns exemplos:

  • O que é o efeito de erros de cache e não há nenhum método para reduzir o impacto?
  • Qual seria o impacto dos discos de estado sólidos?
  • Existe alguma maneira de reduzir a diferença de desempenho entre a solução do PLINQ índice de de threadse as soluções nativa de ? Reduzindo a quantidade de dados, copiando nos métodos FileMmByte IEnumerator.MoveNext e Current de experimentos não mostram algum benefício significativo.
  • É o desempenho de perto o máximo teórico conforme determinado pela largura de banda da memória, velocidade da CPU e outros recursos arquitetônicos?
  • Existe uma maneira de obter desempenho escalável em sistemas de HT (consulte do Figura 5), comparável em sistemas sem HT ( do Figura 1)?
  • Você pode usar o perfil e Visual Studio 2010 as ferramentas para identificar e remover os afunilamentos de desempenho?

Espero que você é capaz de investigar ainda mais.

Johnson (John) M. Hart  é um consultor especializado no Microsoft Windows e arquitetura de aplicativos do Microsoft .NET Framework e desenvolvimento, treinamento técnico e escrita. Ele possui muitos anos de experiência como um engenheiro de software, arquiteto e gerente de engenharia, Inc. de artes Cilk(já que adquirida pela Intel Corp.), Inc. Atlântico do Sierra, Hewlett-Packard Coe o computador Apollo. Ele atuou como professor de ciência do computador por muitos anos e é autor de quatro edições do “ Windows System Programming ” (Addison-Wesley, 2010).

Graças aos seguintes especialistas técnicos para revisão deste artigo: Michael Bruestle,Andrew Greenwald, Troy Magennis and CK Park