114 karma · joined February 16, 2021
So all these event loop frameworks try to implement an async behaviour ontop of a hardware mechanism that is synchronous in it's core. The main issue is that the lowest software construct, the queue used to communicate is built on this cache line ping pong match. What the software want it still a queue, you could still send pointers if the memory they point to has been committed to memory when the receiving core see them. Just remove the inefficient atomic operations way of synchronizing the data between CPUs. Send them using some kind of network pipe instead :-) As you say the memory subsystem is really asynchronous.
I'm convinces this is coming, it should just have arrived 10 years ago...
A simple example is just letting all CPUs in a multi core CPU doing an atomic add at a memory address. The scaling will be exactly 1 with the number of available cores. I realize this is very of topic wrt to this cool article an implementation in zig. It's just that this problem can't really be solved in an efficient manner with todays hardware.
The big frustration with today's multi core CPUs is that there's simply not efficient way to communicate using message passing mechanisms. I think this is something the hardware guys should focus on :-) Provide an async mechanism to communicate between cores, not relying on the cache coherency.
The only truly lock less algorithm that I'm aware of (for most CPU archs) is RCU in the read case.
A slice itself is just a window into a backing array of fixed size. The slice carries three data members. The pointer to the backing array and its remaining capacity and the length of the slice data.
Typically slices are passed around by value but you can take their address and modify a "shared" slice.
The built-in append() returns a new slice by value.
What happens is simply that when appending data to a slice and there is no room in the backing array, a new backing array is allocated that the returned slice points into. The old "input" slice to append is still intact and if some code has access to it, it will look at data stored in the old backing array.
I've constructed similar utility types in C and find them quite convenient. It's very convenient to have the distinction between the backing memory (array) and a slice viewing a portion of it instead of just a dynamic array.
If there where some lossy image format that recorded the image in YUV (or some similar color space) and recorded information beyond the black and white point to be able to recover some details and additionally supported some standardized transforms that could be adjusted on top of the base image I think the need for RAW would diminish. Such transforms would be to set the white point, black point, gamma curve, saturation, white balance. If the standard transform data could be edited in an image editing program, the lossy YUV data would not need to be rewritten causing an image degradation.
There is another aspect, C and C++ are not memory safe languages so the bug may not be particular logical (i.e. some kind of memory corruption). In these cases I actually prefer something to the like of __builtin_trap instead of abort. Calling any code after an invalid invariant has been detected clobbers registers and may make it impossible to investigate the state at the time of the "crash". Some features of modern optimizing compilers make this even worse, such as abort being marked as "noreturn".
range returns index and elements by value. The last example does what you asks of it, it's like complaining something is not returned by reference when it's not. Your mistake. Perhaps some linter could give warnings for it.
Windows 10: Data Units Read: 11 332 875 [5,80 TB] Data Units Written: 8 173 369 [4,18 TB]
Linux: Data Units Read: 5 837 296 [2,98 TB] Data Units Written: 4 891 744 [2,50 TB]