HN user

ot

18,733 karma

Giuseppe Ottaviano

  - Twitter: @ot_y
  - LinkedIn: www.linkedin.com/in/giuseppe-ottaviano-497b7b3
Posts704
Comments878
View on HN
twitter.com 6d ago

Muse Spark 1.1 is now available on OpenRouter

ot
3pts0
openai.com 12d ago

Core dump epidemiology: fixing an 18-year-old bug

ot
3pts0
thinkingmachines.ai 12d ago

The Future Worth Building Is Human

ot
2pts0
ai.meta.com 13d ago

Muse Spark 1.1

ot
413pts214
www.youtube.com 1mo ago

Exposing the Solid State Donut Battery. It's over [video]

ot
2pts0
yourbrainonmoney.substack.com 2mo ago

The Tax of Living in a Low-Trust Society: How Collapsed Trust Costs You

ot
61pts42
worksinprogress.co 2mo ago

The Story of VaccinateCA

ot
1pts0
github.com 2mo ago

Max/MSP external for running neural amplifier captures

ot
9pts0
www.washingtonpost.com 3mo ago

Elon Musk's court battle with Sam Altman exposes Silicon Valley secrets

ot
5pts0
github.com 4mo ago

Generate evolving textures by blending images

ot
1pts0
iggy.apache.org 4mo ago

Apache Iggy's migration to thread-per-core architecture powered by io_uring

ot
2pts0
steve-yegge.medium.com 5mo ago

The Anthropic Hive Mind

ot
4pts1
www.anthropic.com 6mo ago

Designing AI resistant technical evaluations

ot
3pts0
semianalysis.com 1y ago

Meta Superintelligence – Leadership Compute, Talent, and Data

ot
11pts1
www.youtube.com 1y ago

Formalizing a proof in Lean using Github copilot and canonical [video]

ot
2pts0
arxiv.org 1y ago

Qwen3 Embedding: Advancing Text Embedding and Reranking with Foundation Models

ot
1pts0
gamozolabs.github.io 1y ago

Sushi Roll: A CPU research kernel for micro-architectural introspection (2019)

ot
3pts0
github.com 1y ago

Formal Modeling and Analysis of Distributed (Event-Driven) Systems

ot
2pts1
uvdn7.github.io 1y ago

Linear scalable read-write lock

ot
3pts0
www.reuters.com 1y ago

Apple airlifts 600 tons of iPhones from India 'to beat' Trump tariffs

ot
10pts0
www.cnbc.com 1y ago

Trump signs order to establish a sovereign wealth fund that could buy TikTok

ot
10pts1
engineering.fb.com 1y ago

Strobelight: A profiling service built on open source technology

ot
2pts0
www.youtube.com 1y ago

AWS re:Invent 2024 – Dive deep on Amazon S3 [video]

ot
2pts0
11011110.github.io 1y ago

Stack-based graph traversal ≠ depth first search

ot
3pts0
gwern.net 1y ago

Why So Few Matt Levines?

ot
8pts2
github.com 1y ago

Uv: An fast Python package and project manager, written in Rust

ot
4pts1
www.wsj.com 1y ago

Twitter Takeover Is Now the Worst Buyout for Banks Since the Financial Crisis

ot
64pts19
www.youtube.com 1y ago

The Greenwich Meridian is in the wrong place [video]

ot
1pts0
www.jovo.design 1y ago

Design doesn't have to end like this

ot
3pts0
www.mbi-deepdives.com 1y ago

Meta 2Q'24 Update

ot
1pts0

That's a false dichotomy: you optimize both the application and the allocator.

A 0.5% improvement may not be a lot to you, but at hyperscaler scale it's well worth staffing a team to work on it, with the added benefit of having people on hand that can investigate subtle bugs and pathological perf behaviors.

It's not just that zeroing got cheaper, but also we're doing a lot less of it, because jemalloc got much better.

If the allocator returns a page to the kernel and then immediately asks back for one, it's not doing its job well: the main purpose of the allocator is to cache allocations from the kernel. Those patches are pre-decay, pre-background purging thread; these changes significantly improve how jemalloc holds on to memory that might be needed soon. Instead, the zeroing out patches optimize for the pathological behavior.

Also, the kernel has since exposed better ways to optimize memory reclamation, like MADV_FREE, which is a "lazy reclaim": the page stays mapped to the process until the kernel actually need it, so if we use it again before that happens, the whole unmapping/mapping is avoided, which saves not only the zeroing cost, but also the TLB shootdown and other costs. And without changing any security boundary. jemalloc can take advantage of this by enabling "muzzy decay".

However, the drawback is that system-level memory accounting becomes even more fuzzy.

(hi Alex!)

Here RE2 does not fall back to the NFA, it just resets the Lazy DFA cache and starts growing it again. The latency spikes I was mentioning are due to the cost of destroying the cache (involving deallocations, pointer chasing, ...)

are there eviction techniques to guard against this?

RE2 resets the cache when it reaches a (configurable) size limit. Which I found out the hard way when I had to debug almost-periodic latency spikes in a service I managed, where a very inefficient regex caused linear growth in the Lazy DFA, until it hit the limit, then all threads had to wait for its reset for a few hundred milliseconds, and then it all started again.

I'm not sure if dropping the whole cache is the only feasible mitigation, or some gradual pruning would also be possible.

Either way, if you cannot assume that your cache grows monotonically, synchronization becomes more complicated: the trick mentioned in the other comment about only locking the slow path may not be applicable anymore. RE2 uses RW-locking for this.

This is drawing broad conclusions from a specific RW mutex implementation. Other implementations adopt techniques to make the readers scale linearly in the read-mostly case by using per-core state (the drawback is that write locks need to scan it).

One example is folly::SharedMutex, which is very battle-tested: https://uvdn7.github.io/shared-mutex/

There are more sophisticated techniques such as RCU or hazard pointers that make synchronization overhead almost negligible for readers, but they generally require to design the algorithms around them and are not drop-in replacements for a simple mutex, so a good RW mutex implementation is a reasonable default.

You can do even faster, about 8ns (almost an additional 10x improvement) by using software perf events: PERF_COUNT_SW_TASK_CLOCK is thread CPU time, it can be read through a shared page (so no syscall, see perf_event_mmap_page), and then you add the delta since the last context switch with a single rdtsc call within a seqlock.

This is not well documented unfortunately, and I'm not aware of open-source implementations of this.

EDIT: Or maybe not, I'm not sure if PERF_COUNT_SW_TASK_CLOCK allows to select only user time. The kernel can definitely do it, but I don't know if the wiring is there. However this definitely works for overall thread CPU time.

The query is incorrect, it will return any posting that contains the words "vision" and "pro", not necessarily consecutive.

It looks like phrasal search is supported, searching "vision pro" in quotes only returns 212 results worldwide

https://jobs.apple.com/en-us/search?search=%22vision+pro%22&...

Spot-checked a few and they all seem to be Vision Pro related.

--

EDIT: Actually even this is not accurate, as it matches postings with sentences like

Fundamental to the success of iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and Mac ...

but not specific to Vision Pro.

However we can filter on products and services for Vision Pro and visionOS, and it gives 106 results:

https://jobs.apple.com/en-us/search?search=%22vision+pro%22&...

can avoid or defer a lot of the expected memory allocations of async operations

Is this true in realistic use cases or only in minimal demos? From what I've seen, as soon as your code is complex enough that you need two compilation units, you need some higher level async abstraction, like coroutines.

And as soon as you have coroutines, you need to type-erase both the senders and the scheduler, so you have at least couple of allocations per continuation.

It kind of doesn’t matter if there are users [...] The point is that PCG is better

No that's not the point that the article makes and that I'm questioning, it says "everyone shrugged" which implies consensus, and I'm asking for evidence of that consensus, not of the objective quality of the two generators.

Also I don't think that that paragraph is even close to demonstrating "objectively better": the author of PCG pointed out one arbitrary metric, minimum state size, where PCG beats old variants of xorshift* on a statistical test suite, and in the meantime much better variants have come out. That metric is meaningless since everyone uses much bigger state anyway.

RNGs are a tricky subject, there isn't a singular measure of quality, statistical tests are necessary but not sufficient. The best testament to RNG quality is wide adoption, which builds confidence that there aren't undiscovered failure modes.

Since nobody had figured out any downsides to PCG's yet, everyone shrugged and said "might as well just go with that then", and that is where, as of 2019, the art currently stands. The problem is solved, and life is good.

I wonder who "everyone" was, I'm not aware of many high-profile projects adopting PCG as a default. As of 2025, several high-profile runtimes (including all the major browsers) use xorshift variants [1]

Is there a list of users of PCG?

[1] See Adoption section in https://prng.di.unimi.it/

But then you could add another level of slower (but still faster than RAM) and larger cache. So it is after all the CPU caches, but the first of all the memory caches. A more mathematically correct name would be L_omega.

In Defense of C++ 10 months ago

Reminds me of the old quote

everyone only uses 20% of C++, the problem is that everyone uses a different 20%

It is a linear percentage of the amount of time the CPU is not idle. It is not linear in the amount of useful work, but that's not what "utilization" means.

The lie is the assumption that CPU time is linear in useful work, but that has nothing to do with the definition of utilization, it's just something that people sometimes naively believe.

CPU utilization isn't a lie, % CPU utilization is

What do you mean by this? Utilization is, by definition, a ratio. % just determines that the scale is in [0, 100].

Utilization is not a lie, it is a measurement of a well-defined quantity, but people make assumptions to extrapolate capacity models from it, and that is where reality diverges from expectations.

Hyperthreading (SMT) and Turbo (clock scaling) are only a part of the variables causing non-linearity, there are a number of other resources that are shared across cores and "run out" as load increases, like memory bandwidth, interconnect capacity, processor caches. Some bottlenecks might come even from the software, like spinlocks, which have non-linear impact on utilization.

Furthermore, most CPU utilization metrics average over very long windows, from several seconds to a minute, but what really matters for the performance of a latency-sensitive server happens in the time-scale of tens to hundreds of milliseconds, and a multi-second average will not distinguish a bursty behavior from a smooth one. The latter has likely much more capacity to scale up.

Unfortunately, the suggested approach is not that accurate either, because it hinges on two inherently unstable concepts

Benchmark how much work your server can do before having errors or unacceptable latency.

The measurement of this is extremely noisy, as you want to detect the point where the server starts becoming unstable. Even if you look at a very simple queueing theory model, the derivatives close to saturation explode, so any nondeterministic noise is extremely amplified.

Report how much work your server is currently doing.

There is rarely a stable definition of "work". Is it RPS? Request cost can vary even throughout the day. Is it instructions? Same, the typical IPC can vary.

Ultimately, the confidence intervals you get from the load testing approach might be as large as what you can get from building an empirical model from utilization measurement, as long as you measure your utilization correctly.

I'm not sure which comment you're responding to, because I'm not talking about shared_ptr, but about how atomic operations in general are implemented on x86.

I don't believe that shared_ptr uses seq-cst because I can just look at the source code, and I know that inc ref is relaxed and dec ref is acq-rel, as they should be.

However, none of this makes a difference on x86, where RMW atomic operations all lower to the same instructions (like LOCK ADD). Loads also do not care about memory order, and stores sometimes do, and that was what my comment was about.