了解异步Logger中的环形缓冲区 [英] Understand Ring Buffer in async Logger

查看:680
本文介绍了了解异步Logger中的环形缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在log4j2的异步记录器中手动链接

log4j2.asyncLoggerConfigRingBufferSize的默认值为256 * 1024

2561024在这里代表什么?

解决方案

环形缓冲区中的插槽数必须为2的幂.这使您可以继续增加计数器并使用位掩码而不是模来获得计数器的数组索引.

例如,假设我们有一个大小为4的环形缓冲区.索引03是数组中的有效索引.我们要避免检查index++; if (index > 3) { index = 0; }.在紧密的循环中,此if检查可能会使速度变慢.我们可以避免吗?

是的,我们可以.我们可以不检查就增加,而当我们从数组中获得一个值时,我们将忽略4的所有倍数(数组的大小).人们通常为此使用 modulo 操作:value = array[index % 4];

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

这很好,但是我们可以做得更好.模运算适用于任何数组大小,但是出于以下原因,我们选择数组大小为2的幂:位掩码!位掩码可以实现相同的功能,但是速度要快得多(大约快25倍).

这是如何工作的?如果该数组是2的幂,则通过减去1得到其位掩码.然后,当从数组中获取值时,使用此掩码:value = array[index & mask];

对于4,位掩码为4-1 = 3.二进制表示法中的3是11.让我们看一下与之前相同的示例:

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

因此,这与取模相同,但速度更快.同样,关键是数组必须是2的倍数.

回到问题:环形缓冲区中的实际插槽数为262144.文档指出256 * 1024是为了澄清这是2的倍数.

In async logger of log4j2 mannual link

default value of log4j2.asyncLoggerConfigRingBufferSize is 256 * 1024

What does 256 and 1024 represent here?

解决方案

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.

这篇关于了解异步Logger中的环形缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆