Frage

Die Profilerstellung meines Programms und der Funktion print nimmt viel Zeit in Anspruch.Wie kann ich die „rohe“ Byteausgabe direkt an stdout senden, anstatt fwrite zu verwenden, und sie schneller machen (müssen alle 9 Bytes in print() gleichzeitig an stdout senden)?

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

}

Matrix ist global als vorzeichenlose Zeichenmatrix definiert[3][3];

War es hilfreich?

Lösung

IO ist nicht ein kostengünstiger Betrieb. Es ist in der Tat ein Blockierung Betrieb, was bedeutet, dass das Betriebssystem Ihres Prozesses vorgreifen können, wenn Sie write rufen mehr CPU-gebundene Prozesse laufen zu lassen, bevor das IO-Device sind Sie das schriftlich abgeschlossen Betrieb.

Die einzige untere Ebene Funktion, die Sie (wenn Sie die Entwicklung auf einer * nix-Maschine) verwenden können, ist die rohe write Funktion zu nutzen, aber selbst dann wird Ihre Leistung nicht so viel schneller, als es jetzt ist. Einfach ausgedrückt: IO ist teuer.

Andere Tipps

Die am besten bewertete Antwort behauptet, dass IO langsam ist.

Hier ist eine schnelle Benchmark mit einem ausreichend großen Puffer, um die OS aus dem kritischen Leistungs Weg zu nehmen, aber nur, wenn Sie bereit sind, Ihre Ausgabe in riesigen blurps zu erhalten. Wenn Latenz zum ersten Byte Ihr Problem ist, müssen Sie in „tröpfchen“ Modus auszuführen.

schreiben 10 Millionen Datensätze aus einem neun Byte-Array

Mint 12 AMD64 auf 3GHz CoreDuo unter gcc 4.6.1

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

FreeBSD 9 AMD64 auf 2,4 GHz CoreDuo unter Klirren 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

Es gibt nichts, langsam über IO, wenn Sie sich leisten können, richtig puffern.

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

Die rawest Form von Ausgang ist Sie tun können, die wahrscheinlich der write Systemaufruf, wie diese

write (1, matrix, 9);

1 die Dateideskriptor für Standard-out (0 ist Standard in und 2 Standardfehler). Ihr Standard-out wird nur schreiben so schnell wie den man es am anderen Ende (das heißt das Endgerät oder das Programm, das Sie pipeing in) zu lesen, die eher langsam sein könnten.

Ich bin nicht 100% sicher, aber Sie könnten versuchen, auf fd 1 (mit fcntl) non-blocking IO Einstellung und hoffen, dass das Betriebssystem es für Sie puffern, bis sie mit dem anderen Ende verbraucht werden kann. Es ist schon eine Weile, aber ich denke, es funktioniert wie folgt

fcntl (1, F_SETFL, O_NONBLOCK);

YMMV though. Bitte korrigieren Sie mich, wenn ich auf die Syntax falsch bin, wie gesagt, es ist eine Weile her.

Vielleicht ist Ihr Problem ist nicht, dass fwrite () ist langsam, aber dass es gepuffert. Versuchen Sie fordern fflush (stdout) nach dem fwrite ().

Das alles hängt wirklich von Ihrer Definition von langsam in diesem Zusammenhang.

Alle Druck ist ziemlich langsam, obwohl iostreams für den Druck wirklich langsam ist.

Ihre beste Wette wäre printf zu verwenden, etwas entlang der Linien von:

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

Sie können einfach:

std::cout << temp;

printf ist C-Style.

Doch IO-Operationen sind teuer, so nutzen sie mit Bedacht aus.

Wie jeder darauf hingewiesen hat, ist IO in einer engen inneren Schleife teuer.Normalerweise habe ich Matrix auf der Grundlage einiger Kriterien bedingt ausgeschlossen, wenn es zum Debuggen erforderlich war.

Wenn es sich bei Ihrer App um eine Konsolen-App handelt, versuchen Sie, sie in eine Datei umzuleiten. Das geht viel schneller als Konsolenaktualisierungen.z.B. app.exe > matrixDump.txt

Was ist los mit:

fwrite(matrix,1,9,stdout);

das eine wie die zweidimensionalen Arrays den gleichen Speicher in Anspruch nehmen.

Versuchen Sie das Programm zweimal ausgeführt wird. Einmal mit und einmal ohne Ausgang. Sie werden feststellen, dass insgesamt das eine ohne das io der schnellste ist. Auch Sie könnten den Prozess Gabel (oder einen Thread erstellen), ein Schreiben in eine Datei (stdout) und eine der Operationen zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top