Question

Le profilage de mon programme et de la fonction print prend beaucoup de temps.Comment puis-je envoyer la sortie d'octets "bruts" directement vers la sortie standard au lieu d'utiliser fwrite et de la rendre plus rapide (besoin d'envoyer les 9 octets du print() en même temps vers la sortie standard) ?

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);

}

La matrice est définie globalement comme étant une matrice de caractères non signée[3][3] ;

Était-ce utile?

La solution

IO est pas une opération peu coûteuse. Il est, en fait, un blocage fonctionnement, ce qui signifie que le système d'exploitation peut préempter votre processus lorsque vous appelez write pour permettre plus de processus liés à la CPU pour exécuter, avant que l'appareil IO vous écrivez complète le opération.

La fonction de niveau que plus bas, vous pouvez utiliser (si vous développez sur une machine Unix ou Linux), est d'utiliser la fonction write brute, mais même alors votre performance ne sera pas beaucoup plus rapidement que maintenant. Autrement dit: IO est cher.

Autres conseils

Le top rated réponse prétend que IO est lente.

Voici un rapide référence avec un tampon suffisamment grand pour prendre le système d'exploitation sur le chemin de la performance critique, mais seulement si vous êtes prêt à recevoir votre sortie en blurps géant. Si la latence de premier octet est votre problème, vous devez exécuter en mode « dribs ».

Ecrire 10 millions d'enregistrements d'un tableau de neuf octets

Mint 12 AMD64 sur 3GHz CoreDuo sous gcc 4.6.1

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

FreeBSD 9 AMD64 sur 2,4 GHz CoreDuo sous 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

Il n'y a rien lent à IO si vous pouvez vous permettre de tampon correctement.

#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; }
}

La forme la plus brute de la production que vous pouvez faire est probable l'appel système write, comme celui-ci

write (1, matrix, 9);

1 est le descripteur de fichier pour la sortie standard (0 est standard dans, et la figure 2 est une erreur standard). Votre hors norme ne rédigera aussi vite que celui lu à l'autre extrémité (à savoir le terminal, ou le programme que vous pipeing dans) qui pourrait être assez lent.

Je ne suis pas sûr à 100%, mais vous pouvez essayer de régler non-blocage IO sur fd 1 (en utilisant fcntl) et nous espérons le système d'exploitation pour vous mettre en mémoire tampon jusqu'à ce qu'il puisse être consommé par l'autre extrémité. Il a été un certain temps, mais je pense que cela fonctionne comme ceci

fcntl (1, F_SETFL, O_NONBLOCK);

YMMV cependant. S'il vous plaît me corriger si je me trompe sur la syntaxe, comme je le disais, il a été un certain temps.

Peut-être votre problème n'est pas fwrite () est lente, mais qu'il est tamponne. Essayez d'appeler fflush (stdout) après la fwrite ().

Cela dépend tout vraiment de votre définition lente dans ce contexte.

Toutes les impressions est assez lente, bien que iostreams sont vraiment lent pour l'impression.

Votre meilleur pari serait d'utiliser printf, quelque chose le long des lignes 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]);

Vous pouvez simplement:

std::cout << temp;

printf est plus C-Style.

Cependant, les opérations d'entrées-sorties sont coûteuses, afin de les utiliser à bon escient.

Comme tout le monde l'a souligné, les IO dans une boucle interne étroite coûtent cher.J'ai normalement fini par effectuer un cout conditionnel de Matrix basé sur certains critères lorsque cela était nécessaire pour le déboguer.

Si votre application est une application console, essayez de la rediriger vers un fichier, ce sera beaucoup plus rapide que d'effectuer des actualisations de la console.par exemple app.exe > matriceDump.txt

Quel est le problème avec:

fwrite(matrix,1,9,stdout);

l'un et les deux réseaux bidimensionnels occupent la même mémoire.

Essayez d'exécuter deux fois le programme. Une fois avec une sortie et une fois sans. Vous remarquerez que dans l'ensemble, l'un sans l'io est le plus rapide. En outre, vous pouvez bifurquer le processus (ou créer un fil), une écriture dans un fichier (stdout), et celui qui fait les opérations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top