Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing to adjacent array elements from different threads?

Are there any modern, common CPUs where it is unsafe to write to adjacent elements of an array concurrently from different threads? I'm especially interested in x86. You may assume that the compiler doesn't do anything obviously ridiculous to increase memory granularity, even if it's technically within the standard.

I'm interested in the case of writing arbitrarily large structs, not just native types.

Note:

Please don't mention the performance issues with regard to false sharing. I'm well aware of these, but they're of no practical importance for my use cases. I'm also aware of visibility issues with regard to data written from threads other than the reader. This is addressed in my code.

Clarification: This issue came up because on some processors (for example, old DEC Alphas) memory could only be addressed at word level. Therefore, writing to memory in non-word size increments (for example, single bytes) actually involved read-modify-write of the byte to be written plus some adjacent bytes under the hood. To visualize this, think about what's involved in writing to a single bit. You read the byte or word in, perform a bitwise operation on the whole thing, then write the whole thing back. Therefore, you can't safely write to adjacent bits concurrently from different threads.

It's also theoretically possible, though utterly silly, for a compiler to implement memory writes this way when the hardware doesn't require it. x86 can address single bytes, so it's mostly not an issue, but I'm trying to figure out if there's any weird corner case where it is. More generally, I want to know if writing to adjacent elements of an array from different threads is still a practical issue or mostly just a theoretical one that only applies to obscure/ancient hardware and/or really strange compilers.

Yet another edit: Here's a good reference that describes the issue I'm talking about:

http://my.safaribooksonline.com/book/programming/java/0321246780/threads-and-locks/ch17lev1sec6

like image 581
dsimcha Avatar asked Mar 21 '11 16:03

dsimcha


2 Answers

Writing a native sized value (i.e. 1, 2, 4, or 8 bytes) is atomic (well, 8 bytes is only atomic on 64-bit machines). So, no. Writing a native type will always write as expected.

If you're writing multiple native types (i.e. looping to write an array) then it's possible to have an error if there's a bug in the operating system kernel or an interrupt handler that doesn't preserve the required registers.

like image 171
Jim Mischel Avatar answered Sep 24 '22 06:09

Jim Mischel


Yes, definitely, writing a mis-aligned word that straddles the CPU cache line boundary is not atomic.

like image 24
Hans Passant Avatar answered Sep 21 '22 06:09

Hans Passant