496 karma · joined August 3, 2021
"Rule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is.
Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest."
Awesome to see someone continuing in the tradition of free/libre OSS: https://linuxclass.heinz.cmu.edu/doc/Open-Source-books/Free-...
X (Twitter): https://x.com/I4Replication/status/1893842119594258913
Bluesky: https://bsky.app/profile/i4replication.bsky.social/post/3liv...
This also goes to show how every line matters. The one line change was from
if (c >= 93 || c>=0xc6-0x81 && d>0x52)
to if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52)
Link to relevant source code: https://git.musl-libc.org/cgit/musl/tree/src/locale/iconv.c (bug fix is line 505).To explain the bug, EUC_KR is Extended Unicode - Korean. After ASCII characters (0-127), each character is multiple bytes. The logic adjusts to look up from a base-0 index, then checks that both bytes (variables c and d) are in the normalized range. If not, the code adjusts the characters and checks the bounds again. This second check is what contained the bug.
0xc6 - 0x81 is the upper bound of this check (69), not 93. The irony is that the second part of the check gets this correct. I wonder what a `git blame` would reveal about this particular line.
Also, the developer who wrote the parser (Géza Herman) was able to pass all of the tests with strange edge cases from https://seriot.ch/projects/parsing_json.html very quickly: https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00...
NVRAM must maintain atomicity of memory transactions for power failures. Its whole purpose is to store data when you turn your computer off. As a result, when deleteing an EFI variable, you can't manage the individual bytes - you have to delete a whole entry (which can be rather large - based on the EFI specification and the code used for edk2, e.g. https://github.com/tianocore/edk2/blob/83a86f465ccb1a792f5c5...). Deleting these entries might become a problem when you start running against memory constraints and what slots in memory are actually available; hence a possible fragmentation issue.
Additionally, I appreciated how short and specific this blog post was. I enjoy this style of post of someone encountering a problem and solving it.
See also ConeOfArc's video from a month later, https://www.youtube.com/watch?v=RO58B6LcTfM (1M views). The video above is about the initial search and problem, this video is after many Internet strangers worked together to solve it.
I wonder how well this claim holds up under strict scrutiny. At a high level, it makes sense: someone who is a master of their craft will understand their tools and how to use them much better than a beginner starting out. However, I think this is a different claim than the one Paolini makes.
One concrete argument against this is the history of technological progress. With each improvement came a step function in the tools available to builders, creators, etc., and those able to master them achieved a new level of ability and progress not seen before.
There is evidence for this everywhere. In sports, athletes today use modern technologies and knowledge to push their bodies and abilites to new levels (low-oxygen training, equipment specialized in each sport, etc.). If you didn't upgrade your golf clubs from wood to titanium, you are going to be left far behind. In other industries, this applies: a specific example might be in welding, where using a multi-process welder will significantly improve your productivity as well as the quality of your work. [1]
In tech, this distinction is also apparent. There are the dual cases of a programmer being completely ineffective with a modern IDE versus Jeff Dean (or insert your favorite programming legend here) with Emacs (or another text editor). However, this does not mean that a great programmer does not require advanced tools. Great toolchains (compilers, linkers, interpreters, debuggers, etc.), advanced computing capabilities (GPUs for LLMs), and high-speed Internet access will dramatically change the quality of your work.
I think that Paolini is more focused on the idea that a master craftsmen, when compared with a beginner, can still handily defeat the beginner using simple tools, as they understand both the tools and what they are trying to accomplish better. I agree with this point, but think that this relative comparison is distinct from the absolute comparison of a master using simple tools vs. the same master using advanced tools.
I appreicate his larger point that you want high-quality (even if simple) tools that you understand and that will last you a lifetime. This is one of the main benefits of mastering free/open source software [2]: freedom 0 of free software is to run a program as you wish, for any purpose, which is not guaranteed when using proprietary software.
[1] https://www.constructionequipment.com/light-equipment/weldin...
"NOTE: Ensure the device you are running on has no form of hardware acceleration like GPU or the results will be skewed"
How much does adding GPUs affect your performance improvement gains? I understand that the point of this optimization is for CPU-only machines, but it would be interesting to consider the affect your optimizations have when running on GPUs as well.
Other memory safe implementations for C and C++ mentioned/proposed are TrapC (https://vimeo.com/1028578347) and Safe C++ (https://safecpp.org/draft.html).
Fil-C adds capabilities and garbage, though it mentions performace costs of 1.5x - 5x. I would think the capabilties aspect of this language extension would be better addressed by hardware proposals (like CHERI) to prevent adding too much overhead to systems that are performance-critical.
Edit: It also looks like the author could use help porting C programs to Fil-C, see https://news.ycombinator.com/item?id=42158296.
The comments on this fast range reduction are interesting, I recommend reading them (they're much longer than the post itself). Some highlights:
Versions of this exist as early as 1997, in CMU's Common Lisp implementation. Their GitLab is not loading quicky on my computer, but the commit is supposed to be from December by Douglas Crosher (https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-...).
The "Further reading" section (and comments) include implementations of the trick in the wild. Stockfish, the chess engine, used this optimization to reduce memory for storing precomputations of moves in their transposition tables (https://github.com/official-stockfish/Stockfish/commit/2198c...). The commit switches from using bitwise AND (&) and power-of-2 table sizes to using the modulo hash trick, which allows for full use of RAM (even if it's not an exact power of 2). It's also used in Hashtron's modular hash: https://github.com/neurlang/classifier/blob/master/hash/hash..., a straightforward application of the optimization to avoid using modulo.
A GitHub gist with more information: https://github.com/sipa/writeups/tree/main/uniform-range-ext.... It walks through a couple of intuitive explanations on why this technique maintains maximum uniformity in the output distribution, as opposed to the proof in the post.
It's somewhat funny to hear "minimum viable product" in the context of a language standard/specification. I'd never thought of adding a feature to a language in that way before.
The idea of design by contract (DbC) in C++ appears to have been around for a while too. The authors link to a "forthcoming companion paper" (currently a 404 error), but you can find proposals from as early as 2004 with the idea: https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n16...
(and potentially earlier, I just haven't seen one yet)
Some of the key differences are use of standard library and its containers, smart pointers, and other language features that look less like C. In this specific library, this refers to some of the techniques like bit manipulation, manual memory management and string parsing, and using things like enums to improve speed and reduce complexity.
An example of a more robust (but still "classic") library would be something like https://github.com/Tencent/rapidjson.
A concrete example: if you're in a car (an embedded system doing many things at once) and press the brakes, you want the car to be as responsive as possible. A real-time operating system will sacrifice other features of a general purpose OS to guarantee that the brakes are applied within a specified time interval after you press them.
Also, there are responses to a similar comment from when this was previously posted: https://news.ycombinator.com/item?id=32329499
> Normally when reverse engineering a program, it is common to use tracing programs like strace. These tracing programs are quite useful, but they suffer from a design flaw: they use ptrace(2) to accomplish the tracing, which can be detected by the program being traced.
One way to do this would be to call ptrace() from your program and check if it returns the error EPERM. From the man page:
EPERM The specified process cannot be traced. This could be because the tracer has insufficient privileges
(the required capability is CAP_SYS_PTRACE); unprivileged processes cannot trace processes that they
cannot send signals to or those running set-user-ID/set-group-ID programs, for obvious reasons. Alter‐
natively, the process may already be being traced, or (on kernels before 2.6.26) be init(1) (PID 1).
However, this is not the best solution, as if your system has a security policy already in place for ptrace() detection, your process might get detected and killed. Other methods from the calling process might involve timing mechanisms, breakpoint detection, or checking other factors in the process' environment. One problem with the workaround suggested in this post (running a process from qemu-user) is that if it is truly security hardened, it might rely on timing differences smaller than the speed of VM instruction execution.As a user or sysadmin, one way to detect ptrace is to use Yama [1], a Linux kernel module that creates an entry in /proc/sys/kernel/yama/ptrace_scope to configure a user's desired level of ptrace protection, from 0 (normal - any process can call ptrace() on another process owned by the same user) to 3 (completely disabling ptrace).
[1] https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama....
https://en.wikipedia.org/wiki/Michael_Crichton#Gell-Mann_amn...
Before standardized time, it was very difficult to coordinate. Most US towns would have their own local time (think church steeples ringing out the hours), and there were 80+ different time standards across the country. In Massachusetts, for example, there were differences between Boston time and Worcester time, two cities that are ~45 miles apart.
Trains had trouble coordinating: if you're using the same sets of tracks, it's essential that you have a very good idea of where trains are going to be. Unfortunately, there were many collisions between trains as a result of mismatched times between the conductors and stations. [1]
In 1849, William Bond (owner of William Bond & Sons’ Boston) partnered with Harvard to offer the first standardized time from Harvard College Observatory. Time standardization between railroads, which started as a voluntary agreement, became mandatory after the Valley Falls collision. [2] As use of the telegraph spread, time standardization began to spread as well.
The idea of a train conductor holding a pocket watch has become quaint now, but it used to be the difference between life and death for passengers. Part of the cause of the Valley Falls collision (and several others) was a train conductor with a faulty pocket watch.
Another interesting rabbit hole to go down is the standardization of the prime meridian, why Greenwich was chosen [3] (hence Greenwich Mean Time [4]), and why the French were so upset about this (part of the reason time today is called UTC). Part of the reason GMT is the standard has to do with what Sobel discusses at the end of the book [5]: Nevil Maskelyne, the primary antagonist, published The Nautical Almanac, which was for many years the primary reference of sailors across the globe when determining time. All measurements for that book were taken from Greenwich; hence, when governments went to standardize a prime meridian, Greenwich was the obvious choice.
Harvard’s Collection of Historical Scientific Instruments has a fun collection of clocks that illustrate the challenges related to this. [6] It's a small but underrated museum when looking at places to go in Cambridge.
[1] https://news.harvard.edu/gazette/story/2011/11/americas-firs...
[2] https://en.wikipedia.org/wiki/Valley_Falls_train_collision
[3] https://en.wikipedia.org/wiki/Prime_meridian#Prime_meridian_...
[4] https://en.wikipedia.org/wiki/Greenwich_Mean_Time
[5] I don't remember if Sobel discussed this or not in the book
Short cryptanalysis of M-209: http://www.jfbouch.fr/crypto/m209/cryptanalysis.html
Series on how to use the machine: https://www.nf6x.net/2013/03/practical-use-of-the-m-209-ciph...
Paper by James Reeds, Robert Morris and Dennis Ritchie analyzing its security from 1978: https://cryptome.org/2015/12/ReedsTheHagelinCipherBellLabs19...
Apparently the paper by Morris and Ritchie was not supposed to be published; it was instead a technical note. See Ritchie's account: https://www.bell-labs.com/usr/dmr/www/crypt.html
Another good look at LockBit is an investigative report [1] that goes in depth on how they've survived for so long.
[0] http://catless.ncl.ac.uk/risks/go/33/60/7
[1] https://redsense.com/publications/lockbit-story-a-three-year...
[1] https://www.ams.org/notices/201304/rnoti-p461.pdf
[2] A preview: https://www.hup.harvard.edu/file/feeds/PDF/9780674067349_sam...
To give an example, one person (a researcher at DeepMind) recently wrote about specific instances of his uses of LLMs, with anecdotes about alternatives to each example. [1] People on HN had different responses with similar claims with elaborations on how it has changed some of their workflows. [2]
While it would be interesting to see randomized controlled trials on LLM usage, hearing people's anecdotes brings to mind the (often misquoted) phrase: "The plural of anecdote is data". [3] [4]
[1] https://nicholas.carlini.com/writing/2024/how-i-use-ai.html
[2] https://news.ycombinator.com/item?id=41150317
[3] http://blog.danwin.com/don-t-forget-the-plural-of-anecdote-i...
[4] originally misquoted as "Anecdote is the plural of data."