4 ms·
It applies at the socket level as well: modern systems with many sockets (physical processor chips) are like to be NUMA (https://en.wikipedia.org/wiki/Non-unifo
by scott_s 11y ago
It applies at the socket level as well: modern systems with many sockets (physical processor chips) are like to be NUMA (https://en.wikipedia.org/wiki/Non-uniform_memory_access https://en.wikipedia.org/wiki/Non-uniform_memory_access), or non-uniform memory access systems. That means that there is a performance benefit if you access memory on your local NUMA node.
And irrespective of NUMA, it also applies to data sharing between threads: if you have a system with 100s of threads, but you have a multithreaded application written like this:
while (globalFlag) {
doSomeLightWork();
}
Your application will not scale well. The cost of 100s of threads all accessing globalFlag will dominate performance, as the cache line for that variable bounces around the entire system.
All systems are becoming "distributed systems". Even though a single machine will get more and more beefy, we will still have to apply distributed systems thinking in order to take full advantage of that system.
- api 11y agoA chip is a distributed system of transistors too. It's all a matter of scale. The CAP theorem applies there too. Discrete systems choose CA over P, which is why they crash (loss of A) if any single part of them is partitioned in any way.
- hga 11y agoAs I understand it, they're officially considered to be a type of NUMA, cache coherent NUMA or ccNUMA: https://en.wikipedia.org/wiki/Non-uniform_memory_access#Cache_coherent_NUMA_.28ccNUMA.29 https://en.wikipedia.org/wiki/Non-uniform_memory_access#Cach...
- Rusky 11y agoWouldn't globalFlag just be shared in a duplicated cache line between all cores until one of them modifies it?
- scott_s 11y agoIf the code was: while (globalFlag) { ++someValue; } Then you'd probably be okay. But calling a function which does some lightweight but non-trivial work will interfere with your cache. When you come back from the stack frame for doSomeLightWork(), you're more likely to need to load globalFlag from memory. In a multithreaded application where you want to scale to dozens or even hundreds of threads, you have look at even global memory accesses as communication.
- Rusky 11y agoThat still doesn't sound like the cache line "bouncing around" any more than it would if a single-core app did the same work. There's no contention on it the way there would be on a shared mutable value, at least.
- scott_s 11y agoThere is still contention, but not as much. With, say, 8 threads it probably doesn't matter much. But with 128, it starts to matter.