Understand Ring Buffer in async Logger

為{幸葍}努か 提交于 2019-12-11 00:46:49

问题


In async logger of log4j2 mannual link

default value of log4j2.asyncLoggerConfigRingBufferSize is 256 * 1024

What does 256 and 1024 represent here?


回答1:


The number of slots in the ringbuffer needs to be a power of 2. This allows you to keep incrementing the counter and use a bitmask instead of modulo to get the array index from the counter.

For example, suppose we have a ringbuffer of size 4. Indexes 0 to 3 are valid indexes into the array. We want to avoid checking index++; if (index > 3) { index = 0; }. In a tight loop this if check can slow things down. Can we avoid it?

Yes we can. We can just increment without checking, and when we get a value from the array we ignore all multiples of 4 (the size of the array). Often people use the modulo operation for this: value = array[index % 4];

3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...

This works fine, but we can do better. The modulo operation works for any array size, but we chose the array size to be a power of two for a reason: bit masks! A bit mask can achieve the same thing, but much, much faster (about 25 times as fast).

How does this work? If the array is a power of two, we get its bit mask by subtracting one. We then use this mask when getting values from the array: value = array[index & mask];

For 4, the bit mask is 4-1=3. 3 in binary notation is 11. Let’s look at the same example as before:

0011 & 0011 = 0011 (3 & 3 = 3)
1000 & 0011 = 0000 (4 & 3 = 0)
1001 & 0011 = 0001 (5 & 3 = 1)
...

So this does the same as taking the modulo but faster. Again, key point is that the array needs to be a multiple of 2.

Back to the question: The actual number of slots in the ringbuffer is 262144. The documentation states 256 * 1024 to clarify that this is a multiple of 2.



来源:https://stackoverflow.com/questions/50887089/understand-ring-buffer-in-async-logger

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!