fgetsの2億の関数呼び出しは、どのように25,224のシステム呼び出しに変換されますか?

fgetsの2億の関数呼び出しは、どのように25,224のシステム呼び出しに変換されますか?

AI/O効率テストアプエ:

テストファイルは「98.5MB、300万行」という。

ここに画像の説明を入力してください。

「図3.6」で使用されているコード:

#include "apue.h"

#define BUFFSIZE    4096

int
main(void)
{
    int     n;
    char    buf[BUFFSIZE];

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");

    if (n < 0)
        err_sys("read error");

    exit(0);
}

最良の時間を図3.6に示します。:多様に活用BUFFSIZEして最高の時間を選んでください

図3.6のシングルバイト時間:使用BUFFSIZE=1

err_sysエラー処理のためのラッパー関数だけです。

apue.hまた、ラッパーヘッダファイルです。


コードの使用法fgets:

#include "apue.h"
int
main(void)
{
    int c;
    while ((c = fgetc(stdin)) != EOF){
        if (fputc(c, stdout) == EOF)
            err_sys("output error");
    }
        if (ferror(stdin))
            err_sys("input error");
    exit(0);
}

質問ソース:

これらのタイミング数値に関する最後の興味深い点は、このバージョンが図3.6のバージョンよりはるかに高速であることですfgetcBUFFSIZE=1どちらも同じ数の関数呼び出し(約2億)を含みますが、このfgetcバージョンはユーザーのCPU時間が16倍以上速く、クロック時間がほぼ39倍速いです。違いは、readを使用するバージョンは2億の関数呼び出しを実行し、これは再び2億のシステム呼び出しを実行することです。このfgetcバージョンではまだ2億の関数呼び出しを実行しますが、これは単に25,224システムコール。システムコールは通常、通常の関数呼び出しよりはるかに高価です。

テストファイルは98.5MB≒100Mなので、各I / O関数は1億回== 2億回呼び出すので、ここでは問題はありません。

しかし、2億がどのようにfgets解釈されますか?25,224システムコール?

このfgetcバージョンではまだ2億の関数呼び出しを実行しますが、これは25,224システムコール。

どのように25,224計画された?

関連情報