计算循环缓冲区中剩余空间的简化算法?
我想知道是否有比这更简单(单一)的方法来计算循环缓冲区中的剩余空间?
int remaining = (end > start)
? end-start
: bufferSize - start + end;
I was wonder if there is a simpler (single) way to calculate the remaining space in a circular buffer than this?
int remaining = (end > start)
? end-start
: bufferSize - start + end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您担心预测不佳的条件会减慢 CPU 管道的速度,您可以使用以下方法:
但这可能是过早的优化(除非您确实将其识别为热点)。 坚持使用当前的技术,这样更具可读性。
If you're worried about poorly-predicted conditionals slowing down your CPU's pipeline, you could use this:
But that's likely to be premature optimisation (unless you have really identified this as a hotspot). Stick with your current technique, which is much more readable.
嗯...
13 个代币,我赢了吗?
Hmmm....
13 tokens, do I win?
如果循环缓冲区大小是 2 的幂,则可以通过使用
start
和end
表示虚拟流中的位置而不是循环缓冲区存储中的索引来做得更好。 假设start
和end
是无符号的,上面的内容就变成:实际上从缓冲区中获取元素要复杂一些,但开销通常足够小,其幂次方为2 大小的循环缓冲区(仅使用
bufferSize - 1
进行屏蔽),使循环缓冲区的所有其他逻辑更加简单和清晰。 另外,您可以使用所有元素,因为您不再担心end==start
!If your circular buffer size is a power of two, you can do even better by having
start
andend
represent positions in a virtual stream instead of indices into the circular buffer's storage. Assuming thatstart
andend
are unsigned, the above becomes:Actually getting elements out of the buffer is a little more complicated, but the overhead is usually small enough with a power of 2 sized circular buffer (just masking with
bufferSize - 1
) to make all the other logic of your circular buffer much simpler and cleaner. Plus, you get to use all the elements since you no longer worry aboutend==start
!根据 C++ 标准,第 5.6 节第 4 段:
脚注表明最好将商四舍五入为零,这将使余数为负。
因此,
(end - start) % bufferSize
方法不能可靠地工作。 C++ 没有模算术(除了无符号整数类型提供的意义上)。j_random_hacker 推荐的方法是不同的,看起来不错,但我不知道它在简单性或速度方面有任何实际的改进。 将布尔值转换为 int 是巧妙的,但需要心理解析,并且根据编译器和机器的不同,这种调整可能比使用 ?: 更昂贵。
我认为你已经有了最简单、最好的版本,我不会改变它。
According to the C++ Standard, section 5.6, paragraph 4:
A footnote suggests that rounding the quotient towards zero is preferred, which would leave the remainder negative.
Therefore, the
(end - start) % bufferSize
approaches do not work reliably. C++ does not have modular arithmetic (except in the sense offered by unsigned integral types).The approach recommended by j_random_hacker is different, and looks good, but I don't know that it's any actual improvement in simplicity or speed. The conversion of a boolean to an int is ingenious, but requires mental parsing, and that fiddling could be more expensive than the use of ?:, depending on compiler and machine.
I think you've got the simplest and best version right there, and I wouldn't change it.
失去条件:
编辑:
-1
和+1
适用于end == start
的情况。 在这种情况下,此方法将假设缓冲区为空。 根据缓冲区的具体实现,您可能需要调整这些以避免出现相差 1 的情况。Lose the conditional:
Edit: The
-1
and+1
are for the case whenend == start
. In that case, this method will assume the buffer is empty. Depending on the specific implementation of your buffer, you may need to adjust these to avoid an off-by-1 situation.我知道较旧的线程,但认为这可能会有所帮助。
不确定这在 C++ 中实现的速度有多快,但在 rtl 中,如果大小为 n^2
或
Older thread I know but thought this might be helpful.
Not sure how fast this implements in C++ but in rtl we do this if size is n^2
or