3 ms·
> 3. The examples they gave are missing read/write barriers, which are rather important. #2 will only happen during read/write barriers. That is to say: your co
by nwallin 4y ago
> 3. The examples they gave are missing read/write barriers, which are rather important. #2 will only happen during read/write barriers. That is to say: your code is memory-unsafe by default. If order and cache-invalidation matters, you actually need a barrier instruction (!!!) to make sure all these messages are passed to the right place at the right time.
Wait... wait what? Am to understand that if I have code like this:
struct {
int foo;
int bar;
} foobar;
mutex io_mutex;
void baz(int* x, int n) {
*x = 0;
for (int i = 0; i <= n; i++)
*x += i;
lock io_mutex;
print *x;
unlock io_mutex;
}
thread t1 {
baz(&foobar.foo, 10000);
};
thread t2 {
baz(&foobar.bar, 10000);
};
You're saying this code is memory-unsafe without adding barrier instructions? (as opposed to just having terrible performance) (let's also assume the compiler isn't smart enough to just compile that down to `x = n (n-1) / 2;` and actually reads/writes the value in the pointer.)
- vouwfietsman 4y agoBut you aren't actually mixing data here, right? Even though foo and bar could be on the same cache-line, the threads need to read/write either foo OR bar, so the respective core caches being out of sync for the var they don't use does not really cause any safety issues. Maybe I'm missing the point of your example. No idea how these two separate cache lines get merged to main memory in the end though, is there some kind of write mask for that? Also I imagine them being in the same struct is really just an implementation detail and shouldn't actually influence the memory safety?
- dragontamer 4y agolock io_mutex; print \*x; unlock io_mutex; Have you ever looked at lock/unlock code? There's a memory + compiler barrier inside of any mutex. The easiest way to use memory barriers is through locking/unlocking mutexes. Alas, that's too slow for a number of applications, so advanced programmers have begun to use more complicated patterns.