HN user

vlmutolo

1,302 karma
Posts4
Comments290
View on HN

Lots of comments about the price change, but Artifical Analysis reports that 3.1 Flash-Lite (reasoning) used fewer than half of the tokens of 2.5 Flash-Lite (reasoning).

This will likely bring the cost below 2.5 flash-lite for many tasks (depends on the ratio of input to output tokens).

That said, AA also reports that 3.1 FL was 20% more expensive to run for their complete Intelligence index benchmark.

The overall point is that cost is extremely task-dependent, and it doesn’t work to just measure token cost because reasoning can burn so many tokens, reasoning token usage varies by both task and model, and similarly the input/output ratios vary by task.

This article is a little confusing. I think this is a roundabout way to invent the blocked bloom filter with k=2 bits inserted per element.

It seems like the authors wanted to use a single hash for performance (?). Maybe they correctly determined that naive Bloom filters have poor cache locality and reinvented block bloom filters from there.

Overall, I think block bloom filters should be the default most people reach for. They completely solve the cache locality issues (single cache miss per element lookup), and they sacrifice only like 10–15% space increase to do it. I had a simple implementation running at something like 20ns per query with maybe k=9. It would be about 9x that for native Bloom filters.

There’s some discussion in the article about using a single hash to come up with various indexing locations, but it’s simpler to just think of block bloom filters as:

1. Hash-0 gets you the block index

2. Hash-1 through hash-k get you the bits inside the block

If your implementation slices up a single hash to divide it into multiple smaller hashes, that’s fine.

I wonder if the “spawn” API is ever preferable over “fork”. Do we really want to remove context if we can help it? There will certainly be situations where we have to, but then what you want is good compaction for the subagent. “Clean-slate” compaction seems like it would always be suboptimal.

Bevy's Fifth Birthday 12 months ago

What are your thoughts on how Bevy's developing UI toolkit compares (in terms of goals and use cases) to some of the other Rust efforts in the space (egui, xilem, iced, etc.)? Do you expect it will be specialized/limited to scene development for games?

Open models by OpenAI 12 months ago

About 7% of people who have ever lived are alive today. Still pretty lucky, but not quite winning the lottery.

For sure; using total energy delivered makes a lot more sense. But then I think it would be better to use whatever tool humanity has that delivers the max total energy; let’s say Tsar Bomba.

Let’s say the mosquito is 1 again, so Death Star is 34. Tsar Bomba would be about 17.3. Over halfway again!

It’s kind of surprising that our max power output and max energy output are about the same on these scales.

To kill a mosquito, you need "a few tens of millijoules, delivered within a few milliseconds" [0], so let's say 10W. To destroy the Earth (so that it turns into scattered dust and never reforms) you need about 10^32 J [1]; if we assume this is applied over maybe 100s, the laser would be 10^30W.

So the log10 scale goes from 1–30, where mosquitos die at 1 and the Earth dies at 30. The 2 PW in the article is about a 15.3. The Vulcan 20-20 project (set to complete in 2029) will register at about 20PW, or a 16.3 on the mosquito-Death Star scale [2].

So on a log scale, we're over halfway to building the Death Star.

[0] https://spectrum.ieee.org/backyard-star-wars

[1] https://www.scientificamerican.com/article/how-much-energy-w...

[2] https://news.sky.com/story/worlds-most-powerful-laser-to-be-...

Old Growth Wood 1 year ago

A company called Invent Wood (based on research out of UMD) is creating “densified” wood that solves a lot of these problems. They have a process that collapses the cell walls in wood and compresses it to a quarter of its thickness, which gives something like a 10x increase in tensile strength, making it stronger than (a certain type of commonly used) steel by volume and weight. It’s also significantly harder than wood (nearly as hard as the carbon steel people use for knives), doesn’t warp, and is resilient to impacts.

My intuition is that trees need wood to serve purposes greater than just structural integrity. It needs to transport water and nutrients. But for building, we don’t care about these channels and it’s better if we collapse them to encourage stronger hydrogen bonding between cellulose chains.

It sounds like a lot of the benefits of “old growth” wood can be manufactured now. This is probably a good thing for preserving nature; there’s a greater demand for wood with these properties than a supply of old trees. Better to leave the great old trees intact and do cool engineering on cheap trees that grow quickly.

Recent Hacker News discussion:

https://news.ycombinator.com/item?id=44020832

Modern mini-led monitors are very good. The “local” dimming is so local that there isn’t much light bleed even in the worst-case situations (cursor over black background makes it particularly apparent).

The advantage of LEDs is they’re brighter. For example, compare two modern Asus ProArt displays: their mini-LED (PA32UCXR) at 1600 nits and their OLED (PA32DC) at 300ish nits. The OLED is 20% more expensive. These two monitors have otherwise comparable specs. Brightness matters a lot for HDR because if you’re in a bright room, the monitor’s peak brightness needs to overpower the room.

Plus for color managed work, I think LED monitors are supposed to retain their calibration well. OLEDs have to be frequently recalibrated.

And so-called micro-LEDs are coming soon, which promise to make “local” so small that it’s imperceptible. I think the near-term future of displays is really good LEDs.

You can definitely get around a lot of the pain points by using owned types like String as much as possible instead of borrowed types like &str. This is even generally recommended; there’s often no benefit to using the more advanced features of the language.

Usually the advanced features come in when you’re looking for better performance. It helps performance a lot to use reference types (borrowed types) to eliminate deep copies (and allocations) with .clone() in a loop, for example.

Library authors usually don’t have the luxury of knowing how their code will be used downstream, so diligent authors try to make the code reasonably performant and use these advanced language features to do so. You never know if the consumer of your library will use your function in a hot loop.

Bloom Filters 1 year ago

A simple extension of the Bloom filter called “block Bloom filters” fixes this. The idea is that the first hash is the index of a small constant-size block of your array, and the rest of the indices are within that block.

So a single query to the filter should only have one or two cache misses, depending on the size of your block. Or even if your block is larger than a cache line, you can probably issue all the loads at once and only pay for the latency of one memory access.

The downside of doing this is slightly more space usage relative to simple Bloom filters. I’d almost always reach for block Bloom filters, though, once the filter becomes a significant fraction of cache size.

I implemented block bloom filters for fairly large (~GB) arrays and saw about 35ns performance. They’re excellent data structures, pretty much as fast as you can get for approximate membership tests (though other filters have better space-time tradeoffs).

The Underway app is basically an interactive version of this (NYC-specific). It’s just the transit map, but you can click on stations to see current arrival/departure times (“3min”) and MTA notices for lines going through that station.

I think that regardless of what references you have, Rust frees values at the end of their lexical “scope”.

For example, in the linked code below, x is clearly unused past the first line, but its “Drop” implementation executes after the print statement at the end of the function.

The takeaway is that if you want a value to drop early, just explicitly `drop` it. The borrow checker will make sure you don't have any dangling references.

https://play.rust-lang.org/?version=stable&mode=debug&editio...

In general, I think "lifetimes" only exist in the context of the borrow checker and have no influence on the semantics of Rust code. The language was designed so that the borrow checker pass could be omitted and everything would compile and run identically.

I don’t know for sure, but I’d bet that their construction can only implement “Clifford” gates, which are a subset of the gates needed for arbitrary quantum computation.

This is a common situation. Lots of proposed quantum computing architectures are built to support only Clifford gates, and then they have a separate subsystem dedicated to implanting non-Clifford gates. The keyword to search here is “magic state distillation”.

More info here: https://quantumcomputing.stackexchange.com/questions/13629/w...

Generate a stream of random bytes, pre-generation is advised to avoid dominating the benchmark.

Current PRNGs are pretty fast. The Xoroshiro RNG "shootout" benchmark [0] lists some self-reported speeds. They claim 8+ GB/s for even their slowest, highest-quality PRNG. The general-purpose one they recommend is 10GB/s, and 32GB/s when vectorized.

The vectorized versions get close to current DRAM speeds. I think I'd prefer that over reading from a giant table, given that the table reads will have significant implications for caching and disrupt that aspect of the benchmark.

[0] https://prng.di.unimi.it/#shootout

The whole game state is stored in one atom: app/state and entities are again atoms inside the main atom (like in our universe).

I don’t know clojure. Is this normal terminology, ie to use “atom” this way? Seems like a bad name for the concept since the whole idea of “atoms” is that they’re indivisible (back when physics thought they were indivisible).

This is quantum mechanics notation and basic principles.

|x> is pronounced “ket x” (the second half of the intentionally-misspelled word braket), and refers to a quantum state x. The quantum states |0> and |1> refer to the classical states we’re used to.

But as written in the GP comment, a general qubit state is given by a|0> + b|1>, where a and b are complex numbers. This is a “superposition”: the qubit occupies both states simultaneously and will resolve to one of them when observed/measured.

For any quantum state written in this way, we know from quantum mechanics that observing the state will yield a measurement of the state |0> with probability |a|^2 (the norm of the complex number a), and will yield state |1> with probability |b|^2.

The qubit measurement must yield exactly one of a or b, so the probabilities must add up to 1, hence |a|^2 + |b|^2 = 1.