gopalv
Joined 14 years ago
Joined 14 years ago
This is not a new problem, I've had this problem every summer when a new batch of interns show up.
As they say, if an intern can bring down production, it is not the intern's fault.
The interns are generally so much better than me at writing code, but they're not the best at "software development" (I call it "software gardening").
My training regime is to push them up the next 4 leadership levels from "writing code" - delegation, negotiation, vision and inspiration.
Agents are barely at delegation, with multi-agent harnesses.
They don't negotiate with you, they say yes.
Their vision is limited to the context you gave and most of their output is uninspiring (you can smell "Claude did this" on a UX design pattern easily).
But the humans, they've been thrust into delegation on day 1 & unless you've been a tech-lead manager, you probably haven't exercised that skill yet. Even if you have done that, the way agents work is not exactly how humans work [1] in terms of incentives or even try something they think won't work.
If you've been a good IC for years, the company could always afford to hire a human who specializes in those skills and suddenly you've been promoted to a new role without a pay bump or even a choice.
Most of the "Let's add agents and go faster" is basically adding more manpower to a project behind schedule and the payback is missing because that causes communication gaps & dropped messages.
The interesting thing here is that the format is still the same.
I read the original spec and it did call out that
> In practice, data deduplication is handled by pointers, making this type unnecessary.
If any entry can be a pointer, you can shrink this recursively for each field type like a .strings table design.
The weird thing is to see this based off the KV-Cache in the diagrams.
Completely different from the Databricks RAFT [1].
My team built "Dreamtime" earlier this year [2], which used a different mechanism to distill out learnings across multiple sessions.
This didn't pull from the token layer, but from user nudges on unsatisfactory responses.
This works like a sawtooth wave where we accumulate context, check for dissonances (a user gets to say "It depends" and fix it), compress it back, retire the old one.
The audit requirements are the real problem for customers, where you need to be able to ask "When did this change? and who changed it?" which was hard to answer from the lowest layer of the model unless you can retain lineage to the original sessions.
A model we train can't serve as an accomplice to a user who wants to hide some financial crimes by nudging the agent repeatedly.
"A Little Bit of Slope Makes Up For a Lot of Y-Intercept"
https://www.youtube.com/watch?v=mE98Is1quwY
> Pick a radical idea
> Build it over a weekend:
What AI has done is that we can do 10x more work a week, while only delivering 2x to production.
Right now, there are 4 people (and me) working on the same idea in 5 different ways - we're all training small language models, the goal is to get smaller or fewer active parameters.
By next week, we'll have lost on 3 different approaches. I know my approach is a dead-end already, but I'm not ready to give up till the pencils down.
The people I work with are great, because they will see the better solution by the end of it, whether they proposed it or someone else did.
A couple of them have been in the industry for less than 5 years and I feel like their slope is better than mine, which means I'm going to have a good time when they're fully up to speed :)
I would automatically type
(gdb) x/4i $pc
when opening a coredump out of habit.
But using nasm, then looking as gas style assembly in the debugger might be a bit more jarring.
If all python had was __slots__ then we would not be struggling to JIT python.
Tight numerical loops is where the JIT adds performance.
Most performance sensitive features are already available in python between numpy, numba and Cython without really leaving the language core.
You'll mostly be speeding up the slow parts of python, not supercharging the fast parts.
I assume this intended at a class which has already finished writing an AOT compiler and wants to build faster functions than you can derive at a compile time.
> On the first call to a function, the compiler calls compile_me, which reconstructs argument types from their tag bits and builds a temporary type environment. The function body is then optimized using those concrete argument types.
It's been two decades since I have worked on Rhys's brilliant libjit and the work that came before it[1], but the first-call recompilation can mix well with a byte code interpreter as well.
You still need to be able to JIT a whole function with the first-call recompiler here, but you can do even more incremental if you are pairing it with an interpreter which gets to pick up the slack of the JIT.
For example, with an interpreter, I could JIT about ~15% of a function and incrementally implement one opcode at a time without handling the complex ones on day one.
The switch loop with direct threading can jump into a JIT block or the next instruction's compiled location, in identical fashion. So you get to operate register to register for adjacent instructions being JIT'ed together, but write back to heap for the interpreter to take over for an unsupported one.
This is referred to as unrolling in the impl there, because what it really does is partially unroll the for(op in ops) loop and skip the jump to the top when you see a sequence of ops which you can line up together and JIT once.
[1] - https://mirror.linux.org.au/pub/linux.conf.au/2003/papers/Rh...
[2] - https://docs.rs/gnu-libjit/latest/gnu_libjit/struct.Function...
I got one during Santa Cruz wildfires in 2020 and now the kids have a pavlovian reflex to sleep once that gets turned on.
Ikea makes an air-purifier table, which is a end-run around it being a useless box in the room when switched off.
It's fairly expensive, not as good as a purpose built one, but it blends into the average room pretty well.
No, this is still parquet being loaded in.
The "trick" is running through sort order combinations which result in maximum packing in a Dremel style data format (like Parquet).
Here's the trick explained in enough detail to understand, but not enough to copy as-is
https://cloud.google.com/blog/products/bigquery/inside-capac...
Search for the section with
"Capacitor builds an approximation model that takes into account all relevant factors and comes up with a reasonable solution."
or a more detailed dive in the paper (by the favourite author of performance engineers, Daniel Lemire)
Duckdb might not be the reason, the real reason might be AWS.
It's been two years since I worked on this, but AWS Nitro might be triggering a high CPU Steal % when all the cores are busy at the same time.
You can do taskset -c 1-191 <server-process> and get a tiny bit of breathing room there.
I almost always do this above 32 cores, since this lets me always have a nice responsive ssh connection when the rest of the CPUs are churning high.
The more cores you have, the less of a problem sparing 1 core becomes.
This is somewhat unavoidable if you have a number of files and a tight filter which rejects most of them. The footer choice was a bad one in hindsight (not for HDFS), but for anything which uses XOR or other kind of erasure coding. The other other file format I worked with used headers only instead of footers, to save a few ms in latency for the initial GET
I don't think Ducklake can maintain a zone-map or ART index over parquet files, but there is no equivalent of iceberg metadata/something which has min/max/HLL compacted across multiple files yet.
The secondary indexes with file identifiers stored in a sequential file is most likely the next useful thing duckdb can make.
Transparent queries on server/browser in identical sql.
If you play all the tricks Google's Capacitor does to the data layout, you can shove ~2-3 million rows to a browser based query engine in 16-20Mb with duckdb-wasm. We can scale it up to ~1Gb with HTTP range queries, with cache-control.
Then we use Jev to write SQL queries over it in 1-2s, whenever someone has a followup question. Getting Jev to write SQL takes a bit of prep, but my co-founder wrote a paper about clairvoyant query execution a few years ago [1].
I could have 3000 users logged into the same application, but all of them would be bringing their own CPU to run duckdb. My compute scaling problems for my data cube is a solved problem with this approach.
Async io generally causes a CPU bump as a side-effect, when the bottleneck moves from the disk to the CPU (more usually memory bandwidth).
My experience is from a different SQL engine, but the improvement in scan rates directly translates all other operators getting more work to do per unit time.
More CPUs pegged at 100% is always a good sign of smooth flows, but optimizing further requires data layout changes from that point. Even if it is a sub-linear speedup out of concurrency scaling - more with more is still a win, assuming you can pay for more (the Dy-skew paper has an example I can quote).
Buried in the pdf in different sections
> Managers attend meetings far more frequently and spend substantially more time in them than non-managerial employees.
> Separately, interactions with senior colleagues are associated with stronger wage growth
A meeting is called to coordinate or communicate. Wadge's law of meetings tell you which one is which.
But not all coordination is top down, sometimes you need your manager to go negotiate a point with another division.
And neither is all communication, most often you can impress on others the potential of a new approach or the problems with the existing one.
The only trouble for the neurodivergent among us is that "appearing to pay attention" is also communication, same goes for eye-contact or not stuttering.
Corolllary is that skip meetings at your own risk, decisions will be made and you won't be in the room where it happens. And don't be the person who is not welcome in meetings, that too eventually makes your pay suffer.
Switch case is the workhorse of a lexer, parser and execution engine. Lots of them over enums.
This was all mis-optimized for years thanks to Spectre/Meltdown changing how the actual runtime of pre-fetch and speculation used to work.
All my work on CGOTO was made irrelevant by the CPU advances, only to become relevant again when fetch speculation got nerfed.
The indirect call scenario is a bit more interesting, because the JVM has an amazing paper about interface dispatch caches [1] on how to do it runtime instead of compile time.
The PGO is still useful, but not unless you can predict the workload you're going to have - Benchmarketing with a TPC benchmark is a good situation for it.
If you have consistent hardware, tuning an OLTP system for the hardware is much more interesting. Going back in the memory hole, Yahoo used to have a Jeremy Cole build of Mysql which was specially optimized for the raid disk layout that was in production (ZFS came by to fix those issues directly).
https://aidnn.ai
.NET Bytecode -> PHP Bytecode -> Flash Video games -> Big Data -> SQL warehouses -> AI Agents