diff --git a/termbench.cpp b/termbench.cpp index dd2177b..0e1b081 100644 --- a/termbench.cpp +++ b/termbench.cpp @@ -1,3 +1,7 @@ +#define VERSION_NAME "TermMarkV1" + +#define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0])) + struct buffer { int MaxCount; @@ -78,46 +82,20 @@ static void AppendStat(buffer *Buffer, char const *Name, int Value, char const * #define MAX_TERM_WIDTH 4096 #define MAX_TERM_HEIGHT 4096 static char TerminalBuffer[256+16*MAX_TERM_WIDTH*MAX_TERM_HEIGHT]; -static buffer GenerateFrame(int FrameIndex, int Width, int Height) -{ - if(Width > MAX_TERM_WIDTH) Width = MAX_TERM_WIDTH; - if(Height > MAX_TERM_HEIGHT) Height = MAX_TERM_HEIGHT; - - buffer Dest = {sizeof(TerminalBuffer), 0, TerminalBuffer}; - - for(int Y = 0; Y <= Height; ++Y) - { - AppendGoto(&Dest, 1, 1 + Y); - for(int X = 0; X <= Width; ++X) - { - int BackRed = FrameIndex + Y + X; - int BackGreen = FrameIndex + Y; - int BackBlue = FrameIndex; - - int ForeRed = FrameIndex; - int ForeGreen = FrameIndex + Y; - int ForeBlue = FrameIndex + Y + X; - - char Char = 'a' + (char)(((FrameIndex + X)*Y) % ('z' - 'a')); - - AppendColor(&Dest, false, BackRed, BackGreen, BackBlue); - AppendColor(&Dest, true, ForeRed, ForeGreen, ForeBlue); - AppendChar(&Dest, Char); - } - } - AppendColor(&Dest, false, 0, 0, 0); - AppendColor(&Dest, true, 255, 255, 255); - AppendGoto(&Dest, 1, 1); - AppendStat(&Dest, "Cells", Width*Height); - AppendStat(&Dest, "Frame", FrameIndex); - - return Dest; -} #include +#include extern "C" void mainCRTStartup(void) { + char CPU[65] = {}; + for(int SegmentIndex = 0; + SegmentIndex < 3; + ++SegmentIndex) + { + __cpuid((int *)(CPU + 16*SegmentIndex), 0x80000002 + SegmentIndex); + } + for(int Num = 0; Num < 256; ++Num) { buffer NumBuf = {sizeof(NumberTable[Num]), 0, NumberTable[Num]}; @@ -129,14 +107,14 @@ extern "C" void mainCRTStartup(void) HANDLE TerminalOut = GetStdHandle(STD_OUTPUT_HANDLE); DWORD WinConMode = 0; + DWORD EnableVirtualTerminalProcessing = 0x0004; int VirtualTerminalSupport = (GetConsoleMode(TerminalOut, &WinConMode) && SetConsoleMode(TerminalOut, (WinConMode & ~(ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT)) | - ENABLE_VIRTUAL_TERMINAL_PROCESSING)); + EnableVirtualTerminalProcessing)); LARGE_INTEGER Freq; QueryPerformanceFrequency(&Freq); - int SizeMS = 0; int PrepMS = 0; int WriteMS = 0; int ReadMS = 0; @@ -144,35 +122,134 @@ extern "C" void mainCRTStartup(void) int Running = true; int FrameIndex = 0; + int DimIsKnown = false; + + int WritePerLine = false; + int ColorPerFrame = false; + + int Width = 0; + int Height = 0; + + int ByteCount = 0; + int TermMark = 0; + int StatPercent = 0; + + LARGE_INTEGER AverageMark = {}; + int long long TermMarkAccum = 0; + while(Running) { + int NextByteCount = 0; + LARGE_INTEGER A; QueryPerformanceCounter(&A); - CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; - GetConsoleScreenBufferInfo(TerminalOut, &ConsoleInfo); - int Width = ConsoleInfo.srWindow.Right - ConsoleInfo.srWindow.Left; - int Height = ConsoleInfo.srWindow.Bottom - ConsoleInfo.srWindow.Top; + if(TermMarkAccum == 0) + { + AverageMark = A; + } + else + { + int long long AvgMS = 1000*(A.QuadPart - AverageMark.QuadPart) / Freq.QuadPart; + int long long StatMS = 10000; + if(AvgMS > StatMS) + { + TermMark = (int)(1000*(TermMarkAccum / 1024) / AvgMS); + AverageMark = A; + TermMarkAccum = 0; + } + + StatPercent = (int)(100*AvgMS / StatMS); + } + + if(!DimIsKnown) + { + CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; + GetConsoleScreenBufferInfo(TerminalOut, &ConsoleInfo); + Width = ConsoleInfo.srWindow.Right - ConsoleInfo.srWindow.Left; + Height = ConsoleInfo.srWindow.Bottom - ConsoleInfo.srWindow.Top; + DimIsKnown = true; + } - LARGE_INTEGER B; - QueryPerformanceCounter(&B); + if(Width > MAX_TERM_WIDTH) Width = MAX_TERM_WIDTH; + if(Height > MAX_TERM_HEIGHT) Height = MAX_TERM_HEIGHT; + + buffer Frame = {sizeof(TerminalBuffer), 0, TerminalBuffer}; + + for(int Y = 0; Y <= Height; ++Y) + { + AppendGoto(&Frame, 1, 1 + Y); + for(int X = 0; X <= Width; ++X) + { + if(!ColorPerFrame) + { + int BackRed = FrameIndex + Y + X; + int BackGreen = FrameIndex + Y; + int BackBlue = FrameIndex; + + int ForeRed = FrameIndex; + int ForeGreen = FrameIndex + Y; + int ForeBlue = FrameIndex + Y + X; + + AppendColor(&Frame, false, BackRed, BackGreen, BackBlue); + AppendColor(&Frame, true, ForeRed, ForeGreen, ForeBlue); + } + + char Char = 'a' + (char)((FrameIndex + X + Y) % ('z' - 'a')); + AppendChar(&Frame, Char); + } - buffer Frame = GenerateFrame(FrameIndex++, Width, Height); - AppendStat(&Frame, "Sizing", SizeMS, "ms"); - AppendStat(&Frame, "Prep", PrepMS, "ms"); + if(WritePerLine) + { + NextByteCount += Frame.Count; + WriteConsoleA(TerminalOut, Frame.Data, Frame.Count, 0, 0); + Frame.Count = 0; + } + } + + AppendColor(&Frame, false, 0, 0, 0); + AppendColor(&Frame, true, 255, 255, 255); + AppendGoto(&Frame, 1, 1); + AppendStat(&Frame, "Glyphs", (Width*Height) / 1024, "k"); + AppendStat(&Frame, "Bytes", ByteCount / 1024, "kb"); + AppendStat(&Frame, "Frame", FrameIndex); + + if(!WritePerLine) AppendStat(&Frame, "Prep", PrepMS, "ms"); AppendStat(&Frame, "Write", WriteMS, "ms"); AppendStat(&Frame, "Read", ReadMS, "ms"); AppendStat(&Frame, "Total", TotalMS, "ms"); - AppendString(&Frame, VirtualTerminalSupport ? "(Win32 vterm)" : "(NO VTERM REPORTED)"); - LARGE_INTEGER C; - QueryPerformanceCounter(&C); + AppendGoto(&Frame, 1, 2); + AppendString(&Frame, WritePerLine ? "[F1]:write per line " : "[F1]:write per frame "); + AppendString(&Frame, ColorPerFrame ? "[F2]:color per frame " : "[F2]:color per char "); - WriteConsoleA(TerminalOut, Frame.Data, Frame.Count, 0, 0); + if(!WritePerLine) + { + AppendGoto(&Frame, 1, 3); + if(TermMark) + { + AppendStat(&Frame, VERSION_NAME, TermMark, ColorPerFrame ? "kg/s" : "kcg/s"); + AppendString(&Frame, "("); + AppendString(&Frame, CPU); + AppendString(&Frame, " Win32 "); + AppendString(&Frame, VirtualTerminalSupport ? "VTS)" : "NO VTS REPORTED)"); + } + else + { + AppendStat(&Frame, "(collecting", StatPercent, "%)"); + } + } - LARGE_INTEGER D; - QueryPerformanceCounter(&D); + LARGE_INTEGER B; + QueryPerformanceCounter(&B); + NextByteCount += Frame.Count; + WriteConsoleA(TerminalOut, Frame.Data, Frame.Count, 0, 0); + + LARGE_INTEGER C; + QueryPerformanceCounter(&C); + + int ResetStats = false; while(WaitForSingleObject(TerminalIn, 0) == WAIT_OBJECT_0) { INPUT_RECORD Record; @@ -184,22 +261,48 @@ extern "C" void mainCRTStartup(void) (Record.Event.KeyEvent.bKeyDown) && (Record.Event.KeyEvent.wRepeatCount == 1)) { - if(Record.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) + switch(Record.Event.KeyEvent.wVirtualKeyCode) { - Running = false; + case VK_ESCAPE: Running = false; break; + case VK_F1: + { + WritePerLine = !WritePerLine; + ResetStats = true; + } break; + + case VK_F2: + { + ColorPerFrame = !ColorPerFrame; + ResetStats = true; + } break; } } + else if(Record.EventType == WINDOW_BUFFER_SIZE_EVENT) + { + DimIsKnown = false; + ResetStats = true; + } } } - LARGE_INTEGER E; - QueryPerformanceCounter(&E); + LARGE_INTEGER D; + QueryPerformanceCounter(&D); + + PrepMS = GetMS(A.QuadPart, B.QuadPart, Freq.QuadPart); + WriteMS = GetMS(B.QuadPart, C.QuadPart, Freq.QuadPart); + ReadMS = GetMS(C.QuadPart, D.QuadPart, Freq.QuadPart); + TotalMS = GetMS(A.QuadPart, D.QuadPart, Freq.QuadPart); + ByteCount = NextByteCount; + ++FrameIndex; - SizeMS = GetMS(A.QuadPart, B.QuadPart, Freq.QuadPart); - PrepMS = GetMS(B.QuadPart, C.QuadPart, Freq.QuadPart); - WriteMS = GetMS(C.QuadPart, D.QuadPart, Freq.QuadPart); - ReadMS = GetMS(D.QuadPart, E.QuadPart, Freq.QuadPart); - TotalMS = GetMS(A.QuadPart, E.QuadPart, Freq.QuadPart); + if(ResetStats) + { + TermMarkAccum = TermMark = 0; + } + else + { + TermMarkAccum += Width*Height; + } } }