How does 200 million function call of fgets translate into only 25,224 system calls?












0















A I/O efficiency test from APUE:



Test file is said to be "98.5 MB with 3 million lines."



enter image description here



Code used in "Figure 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);
}


best time from Figure 3.6: Use different BUFFSIZE and choose the best time



single byte time from Figure 3.6: Use BUFFSIZE=1



err_sys is merely a wrapper function for error handling.



apue.h is a also wrapper header file.





Code uses 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);
}




The question comes from:




The last point of interest with these timing numbers is that the fgetc version is so much faster than the BUFFSIZE=1 version from Figure 3.6. Both involve the same number of function calls—about 200 million—yet the fgetc version is more than 16 times faster in terms of user CPU time and almost 39 times faster in terms of clock time.
The difference is that the version using read executes 200 million function calls, which in turn execute 200 million system calls. With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls. System calls are
usually much more expensive than ordinary function calls.




The test file is 98.5 MB ≈ 100 M, so 100 million calls for each I/O function call == 200 million calls, no problem here.



But how does 200 million fgets translate into 25,224 system call?




With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls.




How is 25,224 calculated?










share|improve this question




















  • 3





    Presumably fgetc and fputc do internal buffering of ~4k, dividing the whole count by 8k (98.5*1024*1024/4096 = 25216, which is remarkably close to the given number).

    – Olorin
    Mar 5 at 6:01






  • 1





    If so, I think internal buffering should be ~8K. Read function call == write function call = 25224 / 2 = 12612. 98.5*1024*1024/12612 = 8189 B. ~8K data transmitted for each read or write operation. Am I right here?

    – Rick
    Mar 5 at 6:37








  • 1





    Ah, yes, I forgot to double the 98.5 before.

    – Olorin
    Mar 5 at 7:21






  • 1





    You can set the stdio buffer size to whatever you want with setvbuf() (eg. to 1G), and then calculate yet another value ;-)

    – mosvy
    Mar 5 at 11:02






  • 1





    at the contrary, it's functions like fgetc or fputc (which may even be inlined) which need buffering the most, as the example from that book triea to demonstrate. In any case, they use full buffering by default (when not reading from some interactive device) in any implementation I may think of.

    – mosvy
    Mar 5 at 16:41
















0















A I/O efficiency test from APUE:



Test file is said to be "98.5 MB with 3 million lines."



enter image description here



Code used in "Figure 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);
}


best time from Figure 3.6: Use different BUFFSIZE and choose the best time



single byte time from Figure 3.6: Use BUFFSIZE=1



err_sys is merely a wrapper function for error handling.



apue.h is a also wrapper header file.





Code uses 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);
}




The question comes from:




The last point of interest with these timing numbers is that the fgetc version is so much faster than the BUFFSIZE=1 version from Figure 3.6. Both involve the same number of function calls—about 200 million—yet the fgetc version is more than 16 times faster in terms of user CPU time and almost 39 times faster in terms of clock time.
The difference is that the version using read executes 200 million function calls, which in turn execute 200 million system calls. With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls. System calls are
usually much more expensive than ordinary function calls.




The test file is 98.5 MB ≈ 100 M, so 100 million calls for each I/O function call == 200 million calls, no problem here.



But how does 200 million fgets translate into 25,224 system call?




With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls.




How is 25,224 calculated?










share|improve this question




















  • 3





    Presumably fgetc and fputc do internal buffering of ~4k, dividing the whole count by 8k (98.5*1024*1024/4096 = 25216, which is remarkably close to the given number).

    – Olorin
    Mar 5 at 6:01






  • 1





    If so, I think internal buffering should be ~8K. Read function call == write function call = 25224 / 2 = 12612. 98.5*1024*1024/12612 = 8189 B. ~8K data transmitted for each read or write operation. Am I right here?

    – Rick
    Mar 5 at 6:37








  • 1





    Ah, yes, I forgot to double the 98.5 before.

    – Olorin
    Mar 5 at 7:21






  • 1





    You can set the stdio buffer size to whatever you want with setvbuf() (eg. to 1G), and then calculate yet another value ;-)

    – mosvy
    Mar 5 at 11:02






  • 1





    at the contrary, it's functions like fgetc or fputc (which may even be inlined) which need buffering the most, as the example from that book triea to demonstrate. In any case, they use full buffering by default (when not reading from some interactive device) in any implementation I may think of.

    – mosvy
    Mar 5 at 16:41














0












0








0


1






A I/O efficiency test from APUE:



Test file is said to be "98.5 MB with 3 million lines."



enter image description here



Code used in "Figure 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);
}


best time from Figure 3.6: Use different BUFFSIZE and choose the best time



single byte time from Figure 3.6: Use BUFFSIZE=1



err_sys is merely a wrapper function for error handling.



apue.h is a also wrapper header file.





Code uses 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);
}




The question comes from:




The last point of interest with these timing numbers is that the fgetc version is so much faster than the BUFFSIZE=1 version from Figure 3.6. Both involve the same number of function calls—about 200 million—yet the fgetc version is more than 16 times faster in terms of user CPU time and almost 39 times faster in terms of clock time.
The difference is that the version using read executes 200 million function calls, which in turn execute 200 million system calls. With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls. System calls are
usually much more expensive than ordinary function calls.




The test file is 98.5 MB ≈ 100 M, so 100 million calls for each I/O function call == 200 million calls, no problem here.



But how does 200 million fgets translate into 25,224 system call?




With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls.




How is 25,224 calculated?










share|improve this question
















A I/O efficiency test from APUE:



Test file is said to be "98.5 MB with 3 million lines."



enter image description here



Code used in "Figure 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);
}


best time from Figure 3.6: Use different BUFFSIZE and choose the best time



single byte time from Figure 3.6: Use BUFFSIZE=1



err_sys is merely a wrapper function for error handling.



apue.h is a also wrapper header file.





Code uses 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);
}




The question comes from:




The last point of interest with these timing numbers is that the fgetc version is so much faster than the BUFFSIZE=1 version from Figure 3.6. Both involve the same number of function calls—about 200 million—yet the fgetc version is more than 16 times faster in terms of user CPU time and almost 39 times faster in terms of clock time.
The difference is that the version using read executes 200 million function calls, which in turn execute 200 million system calls. With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls. System calls are
usually much more expensive than ordinary function calls.




The test file is 98.5 MB ≈ 100 M, so 100 million calls for each I/O function call == 200 million calls, no problem here.



But how does 200 million fgets translate into 25,224 system call?




With the fgetc version, we still execute 200 million function calls, but this translates into only 25,224 system calls.




How is 25,224 calculated?







files io






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 5 at 5:56









Olorin

3,9481723




3,9481723










asked Mar 5 at 5:42









RickRick

262310




262310








  • 3





    Presumably fgetc and fputc do internal buffering of ~4k, dividing the whole count by 8k (98.5*1024*1024/4096 = 25216, which is remarkably close to the given number).

    – Olorin
    Mar 5 at 6:01






  • 1





    If so, I think internal buffering should be ~8K. Read function call == write function call = 25224 / 2 = 12612. 98.5*1024*1024/12612 = 8189 B. ~8K data transmitted for each read or write operation. Am I right here?

    – Rick
    Mar 5 at 6:37








  • 1





    Ah, yes, I forgot to double the 98.5 before.

    – Olorin
    Mar 5 at 7:21






  • 1





    You can set the stdio buffer size to whatever you want with setvbuf() (eg. to 1G), and then calculate yet another value ;-)

    – mosvy
    Mar 5 at 11:02






  • 1





    at the contrary, it's functions like fgetc or fputc (which may even be inlined) which need buffering the most, as the example from that book triea to demonstrate. In any case, they use full buffering by default (when not reading from some interactive device) in any implementation I may think of.

    – mosvy
    Mar 5 at 16:41














  • 3





    Presumably fgetc and fputc do internal buffering of ~4k, dividing the whole count by 8k (98.5*1024*1024/4096 = 25216, which is remarkably close to the given number).

    – Olorin
    Mar 5 at 6:01






  • 1





    If so, I think internal buffering should be ~8K. Read function call == write function call = 25224 / 2 = 12612. 98.5*1024*1024/12612 = 8189 B. ~8K data transmitted for each read or write operation. Am I right here?

    – Rick
    Mar 5 at 6:37








  • 1





    Ah, yes, I forgot to double the 98.5 before.

    – Olorin
    Mar 5 at 7:21






  • 1





    You can set the stdio buffer size to whatever you want with setvbuf() (eg. to 1G), and then calculate yet another value ;-)

    – mosvy
    Mar 5 at 11:02






  • 1





    at the contrary, it's functions like fgetc or fputc (which may even be inlined) which need buffering the most, as the example from that book triea to demonstrate. In any case, they use full buffering by default (when not reading from some interactive device) in any implementation I may think of.

    – mosvy
    Mar 5 at 16:41








3




3





Presumably fgetc and fputc do internal buffering of ~4k, dividing the whole count by 8k (98.5*1024*1024/4096 = 25216, which is remarkably close to the given number).

– Olorin
Mar 5 at 6:01





Presumably fgetc and fputc do internal buffering of ~4k, dividing the whole count by 8k (98.5*1024*1024/4096 = 25216, which is remarkably close to the given number).

– Olorin
Mar 5 at 6:01




1




1





If so, I think internal buffering should be ~8K. Read function call == write function call = 25224 / 2 = 12612. 98.5*1024*1024/12612 = 8189 B. ~8K data transmitted for each read or write operation. Am I right here?

– Rick
Mar 5 at 6:37







If so, I think internal buffering should be ~8K. Read function call == write function call = 25224 / 2 = 12612. 98.5*1024*1024/12612 = 8189 B. ~8K data transmitted for each read or write operation. Am I right here?

– Rick
Mar 5 at 6:37






1




1





Ah, yes, I forgot to double the 98.5 before.

– Olorin
Mar 5 at 7:21





Ah, yes, I forgot to double the 98.5 before.

– Olorin
Mar 5 at 7:21




1




1





You can set the stdio buffer size to whatever you want with setvbuf() (eg. to 1G), and then calculate yet another value ;-)

– mosvy
Mar 5 at 11:02





You can set the stdio buffer size to whatever you want with setvbuf() (eg. to 1G), and then calculate yet another value ;-)

– mosvy
Mar 5 at 11:02




1




1





at the contrary, it's functions like fgetc or fputc (which may even be inlined) which need buffering the most, as the example from that book triea to demonstrate. In any case, they use full buffering by default (when not reading from some interactive device) in any implementation I may think of.

– mosvy
Mar 5 at 16:41





at the contrary, it's functions like fgetc or fputc (which may even be inlined) which need buffering the most, as the example from that book triea to demonstrate. In any case, they use full buffering by default (when not reading from some interactive device) in any implementation I may think of.

– mosvy
Mar 5 at 16:41










0






active

oldest

votes












Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f504406%2fhow-does-200-million-function-call-of-fgets-translate-into-only-25-224-system-ca%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f504406%2fhow-does-200-million-function-call-of-fgets-translate-into-only-25-224-system-ca%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to make a Squid Proxy server?

第一次世界大戦

Touch on Surface Book