Some problems with Java: buffer line (cache line)

there are some things I don"t quite understand about buffer lines.
1 is cache row invalidation only for volatile, if it is not a volatile variable?
2 when you put it into practice, under what circumstances will the buffer line be populated? Do all classes that are frequently written by member volatile variables in high concurrency have to be populated with buffer lines? All use the disruptor framework?


to be exact, it is not aimed at volatile, but solves the false sharing problem caused by the visibility of volatile memory. If it wasn't for volatile, this kind of problem wouldn't exist.

in practice, it is also more appropriate for volatile for basic data types, because the size of cache line in row buffers is generally only 64 bytes.

in addition to the disruptor framework, you can check Long adder in hystrix and java8


I just read several related articles a few days ago. Tell me about my understanding, the right to communicate, and please correct what is wrong.

first of all, let's talk about my understanding of several related important concepts in the topic:

  1. cache consistency refers to the problem of inconsistent data in multiple CPU caches during concurrent access due to the existence of CPU caches.
  2. The
  3. volatile keyword is a way to use in-memory Barrier in java to resolve cache consistency issues.
  4. cache row is a mechanism used by CPU itself to optimize cache usage efficiency, that is, data operations from memory to CPU cache are performed in behavior units, and this row may contain multiple variables. Because of this mechanism, combined with MESI protocol, pseudo-sharing problems occur when different variables of the same line are operated concurrently, that is, competition for different variables results in Synchronize locks. This unnecessary lock certainly affects performance.

then, in view of the question of the subject, tell me my opinion:

  1. volatile is used to solve the cache consistency problem, because volatile actually only ensures that the operation on the CPU cache immediately flush to memory. At this time, the flush is still in cache behavior unit, that is, your volatile of a single variable in a cache line is actually applied to all variables of the entire cache line, and unnecessary operations of different variables will occur on Synchronize, affecting performance. You need to solve this problem at this time.
  2. cached row padding is designed to solve the performance problems caused by pseudo-sharing by filling out the extra parts of a particular line with useless variables. So when the specific implementation, I think that in general, for performance considerations, it is best to apply cache line filling for volatile variables, and in the case of high concurrent writing, there is no doubt that it must be populated, otherwise the pseudo-sharing problem will really become what they call a "performance killer".
  3. In the case of
  4. without volatile, the cache line still exists, but if concurrent writes are not involved, there will be no pseudo-sharing problem, but if concurrent writes are involved, volatile will be used to solve the cache consistency problem. So from this point of view, volatile can also be regarded as an one-to-one correspondence with cache row padding. However, it is necessary to make it clear that cache lines are not directly related to volatile, but are directly related to concurrent writes of different variables in the same cache line. Volatile is to solve concurrent writes, and cache line padding is to solve pseudo-sharing performance problems caused by flush cache lines during concurrent writes.

finally, I would like to summarize the answers to the two questions:

  1. cache consistency is a problem that needs to be solved. volatile and cache line filling are ways to solve two different but related problems. If there are no concurrent writes, there is no cache consistency problem, and there is no need for volatile and cache lines to be populated
  2. .
  3. cache line filling is to solve the pseudo-sharing problem. Theoretically, all operations that write different variables concurrently to the same cache line will cause pseudo-sharing problem. Under high concurrency, frequent writes of volatile variables definitely need cache line filling . As for the disruptor framework, unfortunately, I don't know much about it yet, but if you can manually populate the cache lines, you don't have to use it, do you?
Menu