Pergunta

Eu estou trabalhando em um pedaço de software científico que é muito intensivo de CPU (seu proc obrigado), mas ele precisa gravar dados no disco com bastante frequência (I / O bound).

Eu estou adicionando paralelização a este (OpenMP) e eu estou querendo saber qual a melhor maneira de atender às necessidades de gravação em disco. Não há nenhuma razão a simulação deve esperar no HDD (que é o que está fazendo agora).

Eu estou procurando um 'melhores práticas' para isso, ea velocidade é o que eu me preocupo com a maioria (estes podem ser extremamente longas simulações).

Graças ~ Alex

Primeiros pensamentos:

ter um processo separado fazer a própria escrita no disco para a simulação tem dois processos: um é vinculado à CPU (simulação) e um é IO-bound (escrevendo arquivo). Isso parece complicado.

Possivelmente um tubo / tampão? Eu sou tipo de novo para estes, talvez isso poderia ser uma solução possível.

Foi útil?

Solução

Se você implementação OpenMP para o seu programa, então é melhor usar #pragma omp única ou #pragma omp mestre da seção paralela para salvar a arquivo. Estes pragmas permitir que apenas um thread para executar alguma coisa. Assim, você código pode parecer como a seguir:

#pragma omp parallel
{
    // Calculating the first part
    Calculate();

    // Using barrier to wait all threads
    #pragma omp barrier

    #pragma omp master
    SaveFirstPartOfResults();

    // Calculate the second part
    Calculate2();

    #pragma omp barrier

    #pragma omp master
    SaveSecondPart();

    Calculate3();

    // ... and so on
}

Aqui equipe de threads vai fazer o cálculo, mas apenas único segmento irá salvar os resultados para o disco.

Parece gasoduto software. Eu sugiro que você considere padrão tbb :: gasoduto da biblioteca Intel Threading Building Blocks. I pode encaminhá-lo para o tutorial sobre dutos de software em http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=25 . Por favor, leia o ponto 4.2. Eles resolveram o problema:. Um segmento para ler a partir da unidade, segundo a processo de ler cordas, um terceiro para salvar a unidade

Outras dicas

Eu diria que a melhor forma seria a de gerar um segmento diferente para salvar os dados, não um processo completamente novo; com um novo processo, você corre o problema de ter que comunicar os dados sejam salvos através do limite de processo, que introduz um novo conjunto de dificuldades.

A primeira solução que vem à mente é muito bonito o que você disse - Tendo em gravações em disco em seu próprio processo com um tubo de one-way do SIM para o escritor. O escritor faz gravações o mais rápido possível (desenho novos dados fora do tubo). O problema com isso é que, se o sim fica muito à frente do escritor, o sim vai ser o bloqueio no tubo escreve qualquer maneira, e será I / O ligado em uma remoção.

O problema é que, de facto, o seu ciclo de simulação não está completa até que seja cuspir os resultados.

A segunda coisa que me ocorre é usar non-blocking I / O. Sempre que as necessidades do sim para escrever, ele deve fazê-lo através de non-blocking I / O. Na próxima necessidade de escrever, então ele pode pegar os resultados da operação de I / O anterior (possivelmente incorrer em uma pequena espera) antes de iniciar o novo. Isso mantém a simulação em execução, tanto quanto possível em paralelo com o I / O sem deixar a simulação chegar muito longe à frente da escrita.

A primeira solução seria melhor se o ciclo de processamento de simulação varia (por vezes menor do que o tempo para uma gravação, às vezes mais), porque, em média, as gravações pode manter-se com o sim.

Se o ciclo de processamento é sempre (ou quase sempre) vai ser mais curto do que o tempo de gravação então você pode muito bem não se preocupar com o tubo e usar apenas non-blocking I / O, porque se você usar o tubo que acabará por encher e o sim vai ficar pendurado no I / O de qualquer maneira.

Uma vez que você está CPU e IO encadernado: Deixe-me adivinhar:? Há ainda muita memória disponível, direito

Se assim você deve amortecer os dados que tem de ser escrito para o disco na memória até certo ponto. Escrevendo pedaços enormes de dados é geralmente muito mais rápido do que escrever pequenas peças.

Para a escrita em si: Considere o uso de memória mapeada IO. Tem sido um tempo desde que eu aferido, mas a última vez que fiz isso foi significativa mais rápido.

Além disso, você pode sempre comércio de CPU vs. IO um pouco. Eu acho que você está escrevendo atualmente os dados como uma espécie de cru, não-comprimido de dados, certo? Você pode obter algum desempenho IO se você usar um esquema de compressão simples de reduzir a quantidade de dados a serem escritos. A biblioteca ZLIB é muito fácil de trabalhar com e comprime muito rápido sobre o nível de compressão mais baixo. Depende da natureza de seus dados, mas se houver uma grande quantidade de redundância em que mesmo um algoritmo de compressão muito bruto pode eliminar a IO vinculado problema.

Um segmento executa continuamente um passo do processo computacionalmente intensivas e, em seguida, adiciona o resultado parcial para uma fila de resultados parciais. Outro segmento remove continuamente resultados parciais da fila e escreve-los no disco. Certifique-se de sincronizar o acesso à fila. Uma fila é uma lista-como estrutura de dados onde você pode adicionar itens para os itens finais e remover da frente.

Faça o seu pedido ter dois tópicos , uma para CPU e um para o disco rígido.

Tenha dados completaram o CPU fio empurrar para uma fila que o segmento de disco rígido, em seguida, puxa a partir de dados vem em.

Desta forma, a CPU apenas se livrar dos dados e permite que alguém pega-lo e o disco rígido apenas espera pacientemente por quaisquer dados na sua fila.

Implementação sábio, você poderia fazer a fila como um tipo de memória compartilhada do objeto, mas acho que um tubo seria exatamente o que você estaria procurando. A CPU simplesmente escreve para o pipe quando necessário. No lado do disco rígido, você acabou de ler o tubo e sempre que você tem dados válidos, proceder a partir daí.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top