Private
Public Access
docs(twitter): add 1857820858162753661 corpus (NOTimothyLottes mmap-log 'no debugger no libc' design)
13-post thread with @bmcnett. Canonical statement of the mmap log design: 'printf-debugging is a horrible term; if you're debugger- free might as well be libc-free.' .log file mapped, first half = lines of fixed 64-char size (cacheline), second half = single 32-bit atomic counter for write position. Writing = increment atomic + dump line. No contention, no file IO, lock-free, captures temporal ordering across threads. Fixed format: r|sc.milmic|line_|hex_____|0000000000-|string... (r=reload, sc.milmic=time since launch, line=source line, hex, dec, msg). Tlk(__LINE__, n, 'msg') API, no printf needed. Examples show startup timing (cart mapping 0.005-0.008s) + Vulkan instance 2.4s with PSO hits at 3K us each. Multi-run log for comparison, Notepad2 F5 to reload. Discussion of fixed line widths in modern era. The cleanest documentation of the mmap log pattern - 8 months before the Aug 2025 CART file announcement.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: "@bmcnett That line of thinking is universal solution to most self-inflicted prob"
|
||||
author: "NOTimothyLottes"
|
||||
handle: "@NOTimothyLottes"
|
||||
post_url: "https://x.com/NOTimothyLottes/status/1857820858162753661"
|
||||
post_id: "1857820858162753661"
|
||||
timestamp: "2024-11-16 16:19:43"
|
||||
post_count: 13
|
||||
reply_count: 0
|
||||
repost_count: 0
|
||||
like_count: 2
|
||||
view_count: 134
|
||||
---
|
||||
|
||||
# @NOTimothyLottes — @bmcnett That line of thinking is universal solution to most self-inflicted prob
|
||||
|
||||
## Post 1 (2024-11-16 15:12:24)
|
||||
|
||||
[0] What a horrible term 'printf-debugging'
|
||||
If you are debugger-free might as well at least be libc-free
|
||||
Here is how I work CPU C code without any debugger in my engines, and how it works better than a debugger for me ...
|
||||
|
||||
## Post 2 (2024-11-16 15:15:24) — reply to Post 1
|
||||
|
||||
[1] First I map a '.log' file, so there is no other file IO
|
||||
(a.) First half of this file (log2 sized file) contains lines of a fixed 64-character size (with the \n at the end)
|
||||
(b.) Second half contains just one 32-bit atomic counter of where to write a line
|
||||
|
||||
## Post 3 (2024-11-16 15:18:27) — reply to Post 2
|
||||
|
||||
[2] So writing a line to this log is 100% overhead-free and lock-free, one just increments the atomic counter, and dumps the comment line in the memory mapped file. Note the 64-byte line size matches a cacheline size, so no contention on the write of the line
|
||||
|
||||
## Post 4 (2024-11-16 15:21:07) — reply to Post 3
|
||||
|
||||
[3] It's ideal for a multi-thread environment, you get correct temporal ordering captured in the log file without any real effect on the scheduling of threads.
|
||||
|
||||
## Post 5 (2024-11-16 15:23:52) — reply to Post 4
|
||||
|
||||
[4] Lines are always in a fixed format
|
||||
r|sc.milmic|line_|hex_____|0000000000-|string...
|
||||
r ... reload count
|
||||
sc.milmic ... time since launch (wraps)
|
||||
line ... source line number (single file program)
|
||||
hex ... hex print of number
|
||||
000 ... decimal print of the number
|
||||
string ... user msg
|
||||
|
||||
## Post 6 (2024-11-16 15:25:16) — reply to Post 5
|
||||
|
||||
[5] I write a line with a simple function call
|
||||
Tlk(__LINE__,n,"msg");
|
||||
Where 'n' is the number, "msg" is a string
|
||||
Don't need printf, this is way better
|
||||
|
||||
## Post 7 (2024-11-16 15:35:45) — reply to Post 6
|
||||
|
||||
[6] Here is an example with a very simple program, just a few first lines. It's nice to automatically see exact timing. Timing since start
|
||||
0.005478 sec ... mapping of the cartridge file
|
||||
0.006850 sec ... page faulting the full cart file
|
||||
0.008230 sec ... window creation done
|
||||
etc
|
||||
|
||||

|
||||
|
||||
## Post 8 (2024-11-16 15:45:00) — reply to Post 7
|
||||
|
||||
[7] Another simple example of a fully pipelined startup, can instantly know where the primary cost is,
|
||||
"Instance begin" and "Instance end" wrap setup of the Vulkan instance, a process which took 2.4 seconds. The 4 PSOs hit in the shader cache at 3k microseconds each
|
||||
|
||||

|
||||
|
||||
## Post 9 (2024-11-16 15:48:37) — reply to Post 8
|
||||
|
||||
[8] The log file keeps multiple runs, so it's easy to compare. Notepad2 it's F5 to reload the log file.
|
||||
|
||||
## Post 10 (2024-11-16 15:58:30) — reply to Post 9
|
||||
|
||||
@NOTimothyLottes So each line is 63 spaces followed by a \n, and those 63 spaces get replaced by printable characters dynamically? I have long dreamed of a text format with a fixed 128 byte line width, and cache line size is gradually switching over from 64 to 128
|
||||
|
||||
## Post 11 (2024-11-16 16:10:50) — reply to Post 10
|
||||
|
||||
@bmcnett Yes fixed character[63]='\n', string fills until then or spaces out. I did 128-char once, but still sometimes use small VGA resolutions. Also written a source editor a few times with this fixed line size, makes for a very simple implementation ...
|
||||
|
||||
## Post 12 (2024-11-16 16:15:50) — reply to Post 11
|
||||
|
||||
@NOTimothyLottes Variable line width ASCII text files made a lot of sense when storage was 100KB or 100MB or 100GB, but now that it's in the terabytes, why even bother
|
||||
|
||||
## Post 13 (2024-11-16 16:19:43) — reply to Post 12
|
||||
|
||||
@bmcnett That line of thinking is universal solution to most self-inflicted problems of the modern era.
|
||||
@@ -0,0 +1,218 @@
|
||||
{
|
||||
"root_post_id": "1857820858162753661",
|
||||
"posts": [
|
||||
{
|
||||
"post_id": "1857803914604618029",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[0] What a horrible term 'printf-debugging'\nIf you are debugger-free might as well at least be libc-free\nHere is how I work CPU C code without any debugger in my engines, and how it works better than a debugger for me ...",
|
||||
"timestamp": "2024-11-16 15:12:24",
|
||||
"media_urls": [],
|
||||
"reply_to_id": null,
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 4,
|
||||
"repost_count": 9,
|
||||
"like_count": 130,
|
||||
"view_count": 19351
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857804669994565771",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[1] First I map a '.log' file, so there is no other file IO\n(a.) First half of this file (log2 sized file) contains lines of a fixed 64-character size (with the \\n at the end)\n(b.) Second half contains just one 32-bit atomic counter of where to write a line",
|
||||
"timestamp": "2024-11-16 15:15:24",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857803914604618029",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 2,
|
||||
"repost_count": 1,
|
||||
"like_count": 15,
|
||||
"view_count": 1778
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857805438151983120",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[2] So writing a line to this log is 100% overhead-free and lock-free, one just increments the atomic counter, and dumps the comment line in the memory mapped file. Note the 64-byte line size matches a cacheline size, so no contention on the write of the line",
|
||||
"timestamp": "2024-11-16 15:18:27",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857804669994565771",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 2,
|
||||
"repost_count": 0,
|
||||
"like_count": 10,
|
||||
"view_count": 1757
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857806110687727898",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[3] It's ideal for a multi-thread environment, you get correct temporal ordering captured in the log file without any real effect on the scheduling of threads.",
|
||||
"timestamp": "2024-11-16 15:21:07",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857805438151983120",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 10,
|
||||
"view_count": 1602
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857806800663244889",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[4] Lines are always in a fixed format\nr|sc.milmic|line_|hex_____|0000000000-|string...\nr ... reload count\nsc.milmic ... time since launch (wraps)\nline ... source line number (single file program)\nhex ... hex print of number\n000 ... decimal print of the number\nstring ... user msg",
|
||||
"timestamp": "2024-11-16 15:23:52",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857806110687727898",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 8,
|
||||
"view_count": 1556
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857807155669225900",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[5] I write a line with a simple function call\nTlk(__LINE__,n,\"msg\");\nWhere 'n' is the number, \"msg\" is a string\nDon't need printf, this is way better",
|
||||
"timestamp": "2024-11-16 15:25:16",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857806800663244889",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 5,
|
||||
"view_count": 1418
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857809793550872629",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[6] Here is an example with a very simple program, just a few first lines. It's nice to automatically see exact timing. Timing since start\n0.005478 sec ... mapping of the cartridge file\n0.006850 sec ... page faulting the full cart file\n0.008230 sec ... window creation done\netc",
|
||||
"timestamp": "2024-11-16 15:35:45",
|
||||
"media_urls": [
|
||||
"https://pbs.twimg.com/media/GchC4NwXQAAbDfS?format=png&name=orig"
|
||||
],
|
||||
"reply_to_id": "1857807155669225900",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 8,
|
||||
"view_count": 1426
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857812120823308592",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[7] Another simple example of a fully pipelined startup, can instantly know where the primary cost is, \n\"Instance begin\" and \"Instance end\" wrap setup of the Vulkan instance, a process which took 2.4 seconds. The 4 PSOs hit in the shader cache at 3k microseconds each",
|
||||
"timestamp": "2024-11-16 15:45:00",
|
||||
"media_urls": [
|
||||
"https://pbs.twimg.com/media/GchFfI5WcAAZ_Al?format=png&name=orig"
|
||||
],
|
||||
"reply_to_id": "1857809793550872629",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 4,
|
||||
"view_count": 1387
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857813028349128825",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "[8] The log file keeps multiple runs, so it's easy to compare. Notepad2 it's F5 to reload the log file.",
|
||||
"timestamp": "2024-11-16 15:48:37",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857812120823308592",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 2,
|
||||
"repost_count": 0,
|
||||
"like_count": 4,
|
||||
"view_count": 1508
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857815519166112244",
|
||||
"author": "bmcnett",
|
||||
"handle": "bmcnett",
|
||||
"text": "@NOTimothyLottes So each line is 63 spaces followed by a \\n, and those 63 spaces get replaced by printable characters dynamically? I have long dreamed of a text format with a fixed 128 byte line width, and cache line size is gradually switching over from 64 to 128",
|
||||
"timestamp": "2024-11-16 15:58:30",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857813028349128825",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 0,
|
||||
"view_count": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857818622271332607",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "@bmcnett Yes fixed character[63]='\\n', string fills until then or spaces out. I did 128-char once, but still sometimes use small VGA resolutions. Also written a source editor a few times with this fixed line size, makes for a very simple implementation ...",
|
||||
"timestamp": "2024-11-16 16:10:50",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857815519166112244",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 1,
|
||||
"view_count": 101
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857819880600531261",
|
||||
"author": "bmcnett",
|
||||
"handle": "bmcnett",
|
||||
"text": "@NOTimothyLottes Variable line width ASCII text files made a lot of sense when storage was 100KB or 100MB or 100GB, but now that it's in the terabytes, why even bother",
|
||||
"timestamp": "2024-11-16 16:15:50",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857818622271332607",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 1,
|
||||
"repost_count": 0,
|
||||
"like_count": 0,
|
||||
"view_count": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"post_id": "1857820858162753661",
|
||||
"author": "NOTimothyLottes",
|
||||
"handle": "NOTimothyLottes",
|
||||
"text": "@bmcnett That line of thinking is universal solution to most self-inflicted problems of the modern era.",
|
||||
"timestamp": "2024-11-16 16:19:43",
|
||||
"media_urls": [],
|
||||
"reply_to_id": "1857819880600531261",
|
||||
"quote_of_id": null,
|
||||
"metrics": {
|
||||
"reply_count": 0,
|
||||
"repost_count": 0,
|
||||
"like_count": 2,
|
||||
"view_count": 134
|
||||
}
|
||||
}
|
||||
],
|
||||
"source_url": "https://x.com/NOTimothyLottes/status/1857820858162753661"
|
||||
}
|
||||
Reference in New Issue
Block a user