1,414 karma · joined April 4, 2022
Website: https://scallywag.software
Bonsai :: A 3D Voxel engine, in a pot: https://github.com/scallyw4g/bonsai
Poof :: A C Metaprogramming Environment: https://github.com/scallyw4g/poof
Reddit: https://reddit.com/r/scallywag_software
The best argument I've ever come across against using RAII is that you end up with these nests of objects pointing to one another, and if something fails, the cleanup code can really only do one thing, which is unwind and deallocate (or whatever the cleanup path is). This structure, generally, precludes the possibility of context dependent resource re-usage on initialization failure, or on deallocation, because you kind of have to have only one deallocation path. Obviously, you could imagine supporting in an RAII context, but, the point is that you probably have to put a fair bit of conscious effort into doing that, whereas if you have a less .. rigid.. ownership model, it becomes completely trivial.
I agree that the allocation model and ownership model are independent concepts. I mentioned arena allocation because the people I know that reject the traditional C++ ownership model generally tend to favor arenas, scratch space, freelists, etc. I'm specifically interested in an ownership model that works with arenas, and tracks ownership of the group of allocations, as opposed to the typical case we think about with RAII where we track ownership of individual allocations.
Edit: clarity
I identify as a caveman and I fucking love it. I build a 250k sloc C++ project hundreds of times a day with a 50 line bash script. Works every time, on any machine, everywhere.
Regardless, storage and retroactive processing wasn't part of the problem. The problem was explicitly "parse json records as they come in, in a big batch, and increment some integers in a database".
I'm not going to figure out what the upper limit is on a single bare-metal machine, but you can be damn sure it's a metric fuck-ton higher than 1gb/day. You can do a lot with a 10TB of memory and 256 cores.
It follows that, at some threshold number of users, it becomes much cheaper to ship a Linux distro than to continue to support Windows proper.
:shrug:
Guess we'll see in 15 years.
I can maybe make a case for running in containers if you need some specific security properties but .. mostly I think the proliferation of 'fucked up piles of shit' is the problem.
Said another way, how do you have a meaningful conversation about scaling with a person who thinks their application is huge, but in reality only requires a tiny fraction of a single machine? Sometimes, there's such a massive gulf between perception and reality that the only thing to do is chuckle and move on.
I also believe that running a broken interview process actively selects for qualities you actually don't want, so it's much more likely that teams conducting those interviews aren't teams I want to work on.
Edit: As credence for my claims, the best team I've ever worked on was a team I did 90%+ of the hiring for, and we didn't do any of the 'typical' interview bullshit most companies do.
What we did instead was sit people down and have deep technical conversations about systems they'd worked on in the past. The candidate would explain, in as much detail as they could muster, a system they'd worked on in the past, down to the lowest level details. Usually, they would talk to us for at least 20-30 minutes, then, we (the interviewers) would pose questions, usually starting with the form 'if we changed X, what effect would it have'. Doing interviews in this style make a few things immediately obvious:
1. Did the candidate have a deep, systemic understanding of the system they worked on?
2. Does the candidate have a good mental model for evaluating change in the system?
That's how I conduct interviews, and unsurprisingly, when I get interviewed like that, my success rate is 100%. I don't think I've ever done an interview like that which did not result in an offer.
Anyways, there's some rambling and unsolicited opinions for you :)
I optimize my answers for the companies I want to work for, and get rejected by the ones I don't. The hardest part of that strategy is coming to terms with the idea that I constantly get rejected by people that I think are mostly <derogatory_words_here>, but I've developed thick skin over the years.
I'd much rather spend a year unemployed (and do a ton of painful interviews) and find a company who's values align with mine, than work for a year on a team I disagree with constantly and quit out of frustration.
I think a lot of people don't realize machines come with TBs of RAM and hundreds of physical cores. One machine is fucking huge these days.
To your point about profile results, any profiler that adds more than a couple percentage points at runtime basically destroys the profile results (less than one percent is the acceptable margin, for me). Adding 50% is just laughable, and at the time I looked that was the best available option.
At the time, I was trying to profile ML models and some tooling surrounding them. There are several reasons you want your profiler to be low overhead:
1. If the profiler does a ton of useless shit (read: is slow), it has many deleterious effects on the program being profiled. It can evict entries from the CPUs ICache, DCache, and TLB entries to name a few, all of which can cause huge stalls and make something (such as a scan over tensor memory, for example) many times slower than it would be otherwise. You become unable to reason about if something is taking a long time because it's doing something stupid, or if the profiler is just screwing up your day. Introducing this kind of noise to your profile makes it nearly impossible to do a good job at analysis, let alone optimizing anything.
2. Somewhat unrelated to performance, but, you really want to know more than "this function take up a lot of time", which is basically all sampling profilers tell you. If you look at a flame graph and it says "fooFunc()" takes up 80% of the time, you have no idea if that's because one call to "fooFunc()" took 79% and the rest were negligible, or if they're all slow, or just a handful. That is key information and, in my mind, basically makes sampling profilers unsuitable for anything but 'approxamizing'. Which can be useful, and is often good enough, but if you need to optimize something for real, a sampling profiler exhausts it's usefulness pretty quick.
Anyways .. there are some random thoughts for you :)
I wonder what the overhead of sys.monitoring is. It is possible to instrument functions like this without using that API.. you can just walk the AST at startup and do it yourself. Would be interesting to see a very minimal instrumenting profiler that did that and compare the two.
I also love the 'targeted'/instrumenting profiling API. I think sampling profilers are good at scratching the surface, but quickly run out of useful information when getting down to the goods. Happy to see people doing instrumenting profilers.
Thanks for sharing :)
Sure, at the limit, I agree with you, but in reality, relying on the compiler to do any optimization that you care about (such as inlining an indirect function call in a hot loop) is incredibly unwise. Invariably, in some cases it will fail, and it will fail silently. If you're writing performance critical code in any language, you give the compiler no choice in the matter, and do the optimization yourself.
I do generally agree that in the case of qsort, it's an API design flaw
I've written a small handful of articles, with the most interesting one being about writing a state-of-the-art AVX2 Perlin Noise implementation, which improved on the then-SOTA by 1.8x