Pergunta

Profiling meu programa e a impressão função está levando muito tempo para executar. Como posso enviar "raw" saída byte diretamente para stdout em vez de usar fwrite, e torná-lo mais rápido (necessidade de enviar todos os 9bytes no print (), ao mesmo tempo para o stdout)?

void print(){
    unsigned char temp[9];

    temp[0] = matrix[0][0];
    temp[1] = matrix[0][1];
    temp[2] = matrix[0][2];
    temp[3] = matrix[1][0];
    temp[4] = matrix[1][1];
    temp[5] = matrix[1][2];
    temp[6] = matrix[2][0];
    temp[7] = matrix[2][1];
    temp[8] = matrix[2][2];

    fwrite(temp,1,9,stdout);

}

matriz é definida globalmente a ser uma matriz de char não assinado [3] [3];

Foi útil?

Solução

IO não é uma operação barata. É, de fato, um bloqueando operação, o que significa que o sistema operacional pode antecipar o seu processo quando você chamar write para permitir mais processos CPU-bound para executar, antes do dispositivo IO você está escrevendo para completa a Operação.

A função de nível menor apenas que você pode usar (se você está desenvolvendo em uma máquina * nix), é usar a função write cru, mas mesmo assim o seu desempenho não será que muito mais rápido do que é agora. Simplificando: IO é caro.

Outras dicas

Os mais votados reivindicações de resposta que IO é lento.

Aqui está uma referência rápida com um buffer suficientemente grande para levar o sistema operacional fora do caminho crítico de desempenho, mas apenas se você está disposto a receber a sua saída em blurps gigantes. Se a latência para o primeiro byte é o seu problema, você precisa executar no modo "dribs".

Escrever 10 milhões de registros de uma matriz de nove byte

Mint 12 AMD64 em 3GHz CoreDuo sob gcc 4.6.1

   340ms   to /dev/null 
   710ms   to 90MB output file 
 15254ms   to 90MB output file in "dribs" mode 

FreeBSD 9 AMD64 em 2.4GHz CoreDuo sob clang 3.0

   450ms   to /dev/null 
   550ms   to 90MB output file on ZFS triple mirror
  1150ms   to 90MB output file on FFS system drive
 22154ms   to 90MB output file in "dribs" mode

Não há nada lento cerca de IO se você pode pagar para o buffer corretamente.

#include <stdio.h> 
#include <assert.h> 
#include <stdlib.h>
#include <string.h>

int main (int argc, char* argv[]) 
{
    int dribs = argc > 1 && 0==strcmp (argv[1], "dribs");
    int err;
    int i; 
    enum { BigBuf = 4*1024*1024 };
    char* outbuf = malloc (BigBuf); 
    assert (outbuf != NULL); 
    err = setvbuf (stdout, outbuf, _IOFBF, BigBuf); // full line buffering 
    assert (err == 0);

    enum { ArraySize = 9 };
    char temp[ArraySize]; 
    enum { Count = 10*1000*1000 }; 

    for (i = 0; i < Count; ++i) {
        fwrite (temp, 1, ArraySize, stdout);    
        if (dribs) fflush (stdout); 
    }
    fflush (stdout);  // seems to be needed after setting own buffer
    fclose (stdout);
    if (outbuf) { free (outbuf); outbuf = NULL; }
}

A forma mais crua de saída que você pode fazer é a provável a chamada de sistema write, como este

write (1, matrix, 9);

1 é o descritor de arquivo para fora padrão (0 é no padrão, e 2 é o erro padrão). O seu fora padrão só vai escrever tão rápido quanto a lê-lo na outra extremidade (ou seja, o terminal, ou o programa que está pipeing em) que pode ser bastante lento.

Eu não estou 100% de certeza, mas você pode tentar definir IO não-bloqueável em fd 1 (usando fcntl) e espero que o OS vai tamponar-lo para você até que possa ser consumido pela outra extremidade. Tem sido um tempo, mas eu acho que funciona assim

fcntl (1, F_SETFL, O_NONBLOCK);

YMMV embora. Por favor me corrijam se eu estiver errado sobre a sintaxe, como eu disse, tem sido um tempo.

Talvez o seu problema não é que fwrite () é lento, mas que é tamponado. Tente chamar fflush (stdout) após o fwrite ().

Isso tudo realmente depende de sua definição de lenta neste contexto.

Toda a impressão é bastante lento, embora iostreams são muito lentas para impressão.

Sua melhor aposta seria a utilização de printf, algo ao longo das linhas de:

printf("%c%c%c%c%c%c%c%c%c\n", matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0],
  matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2]);

Você pode simplesmente:

std::cout << temp;

printf é mais C-Style.

No entanto, operações de IO são caros, por isso usá-los sabiamente.

Como todos apontou IO em loop interno apertado é caro. Eu normalmente acabou fazendo cout condicional de Matrix com base em alguns critérios quando necessário para depurá-lo.

Se seu aplicativo é console app tente redirecionando-o para um arquivo, ele será muito mais rápido do que fazer atualizações de console. por exemplo app.exe> ??matrixDump.txt

O que há de errado com:

fwrite(matrix,1,9,stdout);

tanto uma como as duas matrizes dimensionais ocupam a mesma memória.

Tente executar o programa duas vezes. Uma vez com saída e uma vez sem. Você vai notar que, em geral, a um sem o io é o mais rápido. Além disso, você poderia desembolsar o processo (ou criar um segmento), uma escrita em um arquivo (stdout), e um fazendo as operações.

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