문제

내 프로그램과 함수 인쇄를 프로파일링하는 데 많은 시간이 걸립니다.fwrite를 사용하는 대신 "원시" 바이트 출력을 stdout으로 직접 보내서 속도를 더 빠르게 만드는 방법은 무엇입니까(동시에 stdout으로 print()의 9바이트를 모두 보내야 함)?

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

}

행렬은 부호 없는 char 행렬[3][3]로 전역적으로 정의됩니다.

도움이 되었습니까?

해결책

IO는 저렴한 작업이 아닙니다. 사실, 그것은 a입니다 블로킹 운영, 즉 OS가 전화 할 때 프로세스를 선점 할 수 있음을 의미합니다. write 더 많은 CPU 결합 프로세스가 실행되도록하려면 IO 장치가 작성되기 전에 작업을 완료합니다.

당신이 사용할 수있는 유일한 낮은 레벨 기능 ( *nix 기계에서 개발하는 경우)은 원시를 사용하는 것입니다. write 기능이지만, 심지어 성능은 지금보다 훨씬 빠르지 않을 것입니다. 간단히 말해 : IO는 비싸다.

다른 팁

최고 등급의 답변은 IO가 느리다고 주장합니다.

다음은 중요한 성능 경로에서 OS를 빼앗을 수있는 충분히 큰 버퍼가있는 빠른 벤치 마크입니다. 경우에만 당신은 거대한 블러프로 당신의 출력을 기꺼이받을 것입니다. 첫 바이트에 대한 대기 시간이 문제 인 경우 "Dribs"모드에서 실행해야합니다.

9 바이트 배열에서 천만 레코드를 작성하십시오

GCC 4.6.1에 따른 3GHz Coreduo에서 Mint 12 AMD64

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

Clang 3.0에 따른 2.4GHz Coreduo에서 Freebsd 9 AMD64

   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

제대로 버퍼링 할 여유가 있다면 IO에 대해서는 느리게는 없습니다.

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

당신이 할 수있는 가장 원시적 인 형태는 write 이와 같은 시스템 호출

write (1, matrix, 9);

1은 Standard Out의 파일 설명 자입니다 (0은 표준 IN이고 2는 표준 오류입니다). 표준 아웃은 다른 쪽 끝에서 읽는 것 (즉, 터미널 또는 파이프가있는 프로그램)만큼 빠르게 작성됩니다.

100% 확실하지는 않지만 FD 1에서 비 블로킹 IO를 설정하려고 시도 할 수 있습니다 (사용 fcntl) 그리고 OS가 다른 쪽 끝에 소비 될 때까지 OS가 당신을 위해 그것을 완충하기를 바랍니다. 오랜 시간이 지났지 만 이렇게 작동한다고 생각합니다.

fcntl (1, F_SETFL, O_NONBLOCK);

그래도 ymmv. 내가 구문에 틀렸다면 제가 말했듯이, 그것은 오랜 시간이 지났습니다.

아마도 당신의 문제는 fwrite ()가 느리지 않지만 버퍼링 된 것입니다. fwrite () 후 fflush (stdout)를 호출하십시오.

이것은 실제로이 맥락에서 느린 정의에 달려 있습니다.

ioStream은 인쇄가 실제로 느리지 만 모든 인쇄는 상당히 느립니다.

가장 좋은 방법은 다음과 같은 선을 따라 인쇄물을 사용하는 것입니다.

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

당신은 간단히 할 수 있습니다 :

std::cout << temp;

printf 더 C 스타일입니다.

그러나 IO 작업은 비용이 많이 들기 때문에 현명하게 사용하십시오.

모두가 지적했듯이 단단한 내부 루프의 IO는 비용이 많이 듭니다.나는 일반적으로 디버깅이 필요할 때 몇 가지 기준에 따라 Matrix의 조건부 계산을 수행했습니다.

앱이 콘솔 앱인 경우 파일로 리디렉션해 보면 콘솔 새로 고침을 수행하는 것보다 훨씬 빠릅니다.예: app.exe > MatrixDump.txt

무엇이 문제가 있습니까 :

fwrite(matrix,1,9,stdout);

하나와 2 차원 배열 모두 동일한 메모리를 차지합니다.

프로그램을 두 번 실행 해보세요. 한 번 출력이 있고 한 번은 없습니다. 전체적으로 IO가없는 것이 가장 빠릅니다. 또한 프로세스를 포크 (또는 스레드를 생성), 하나는 파일 (STDOUT) 및 작업을 수행 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top