refterm icon indicating copy to clipboard operation
refterm copied to clipboard

Figure out what really happens in conhost

Open cmuratori opened this issue 3 years ago • 4 comments

Now that I've started looking at performance of refterm, I've noticed that if you don't use stdio and instead use Windows' native WriteFIle, conhost no longer seems to take a significant amount of time.

splat.cpp is the stdio version of splat, and splat2.cpp is the Windows-native version. If you run both, you can see a dramatic difference between the two. While both are fast with fastpipe, splat2 is barely slower with fastpipe off, whereas splat is much slower with fastpipe off.

I am hoping that I just messed up the timings here, because I only looked at this briefly. But if I didn't, and there's something else going on here, it would be nice to know what it is!

- Casey

cmuratori avatar Jul 05 '21 03:07 cmuratori

It looks like this is about the write pattern. Apparently, changing from text to binary mode largely fixes the problem, because stdio no longer goes through CR/LF buffering. This would seem to imply that conhost suffers from handoff overhead of some kind, such that writing one n-byte buffer is much faster than writing 10 (n/10)-byte buffers. This should be more rigorously verified, of course, but it is interesting.

- Casey

cmuratori avatar Jul 06 '21 00:07 cmuratori

Does changing stuff with _set_fmode(_O_BINARY); fix the issue even with stdio slowness? Apparently, _O_BINARY needs to be explictly passed to get binary file descriptors on Windows when calling _open(); I am assuming they default to using text mode unless someone changes the setting?

guilt avatar Jul 15 '21 12:07 guilt

It fixes slowness for how splat code is using large writes. If you do small writes, does not matter with fwrite+binary-mode or WriteFile, then there will be slowness regardless. That was the reason why enabling binary mode on stdout seems to "fix it" for splat, because then stdio stopped doing small writes and used code to call WriteFile on whole buffer that is passed it.

mmozeiko avatar Jul 15 '21 12:07 mmozeiko

Apparently, changing from text to binary mode largely fixes the problem, because stdio no longer goes through CR/LF buffering.

I am not a programmer, but does changing the buffering mode with setvbuf to full buffering make a difference? setvbuf(stdout, NULL, _IOFBF, BufSize);

OetkenPurveyorOfCode avatar Jan 21 '22 19:01 OetkenPurveyorOfCode

I've had good results using full buffering and a large buffer for a logging terminal even though the documentation says "stream must refer to an open file that has not undergone an I/O operation since it was opened" and you have to use _fflush(stdout); for partial buffers

spudwa avatar Oct 11 '22 09:10 spudwa