Hacker News new | ask | show | jobs
by ajross 4862 days ago
Hm... (c) needs a little qualification. Certainly in a multithreaded environment it's possible to end up in a cache contention situation accidentally, simply because you or the compiler happened to put two "write often from a single thread" values in the same cache line. Think of things like global/singleton objects which doesn't really need to be shared but are. A multiprocess design that limited shared memory to stuff that's truly shared won't have that pitfall.
1 comments

No, that's not right.

Cache conflicts happen between processes in the same way, and for the same reasons, and just as often, as they do between threads.

No, you misunderstand. A global Java object (or whatever) in one process will be shared across all threads. If it has fields that get written "often" they are likely to end up thrashing the L1/L2 caches with snoop ejections. Often those writes are essentially spurious (global statistics, "current" thingy pointers) and don't really need to be shared across all threads. This really happens, and it's very easy to do.

An essentially identical architecture that defined the same object within a single address space is, quite clearly, not going to be subject to that bug.

An essentially identical architecture that defined the same object within a single address space

Well, then it would be the same architecture, because the one you described (one process with multiple threads) is also a single address space.

Still, I think you're wrong. The cache system doesn't have any awareness of threads or processes. So, you get spurious evictions all the time from completely unrelated programs, no matter what you do. Or from unrelated data in the same program that just happens to map to the same cache line.

If you still disagree with me and you can give me a specific example, I'd really appreciate it, because if I am misunderstanding something, it's a big deal, and I want to double check myself.

The cache system isn't aware of threads or processes, but it's clearly aware of address spaces. Make a big global Foo object in a single process and spawn a hundred threads to write to it. They'll be contending on the same cache line. You're with me that far, right?

Now take the same architecture and spawn a hundred processes. Those Foo objects now live in different physical pages and thus writes to them from all the processes live happily in L1 cache.

Obviously not all architectures work like this. If Foo is "really" shared, then nothing can help the contention. But usually it's not, it's just that the code was written by someone who didn't think about cache contention. That kind of performance bug is really easy to write. And a reasonable fix for it is "don't use multithreaded architectures when you don't need them".

The cache system isn't aware of threads or processes, but it's clearly aware of address spaces.

No, it's definitely not aware of address spaces. Caching is based on the physical address.

In fact, it's based on the low-order bits of the physical address. So, things that are in different physical pages but have the same lower-order bits can conflict.