LMAX-Exchange / disruptor

High Performance Inter-Thread Messaging Library
http://lmax-exchange.github.io/disruptor/
Apache License 2.0
17.48k stars 3.93k forks source link

Is there a performance problem with the next(n) method? #482

Open chenggwang opened 2 months ago

chenggwang commented 2 months ago

In the next(n) method we used long wrapPoint = nextSequence - bufferSize;wrapPoint > cachedGatingSequence in determining whether a wrap occurred or not.For example, in the following figure:

无标题

Let's say we've posted a round, at which point cursor=15 and cachedGatingSequence=1. The producer calls next(4) again; the pseudo-code logic looks like this:

nextSequence=19=15+4;
wrapPoint = 19-16=3;
wrapPoint> cachedGatingSequence(3>1);
parkNanos(1L);

but it is clear that there are already two positions that can be filled, but we have to wait for “C” and “D” to be consumed before we can post an event to fill. General machine 100 times the value of the simple assignment of about 1500-5000 nanoseconds, assuming that we next (200) read and write events are simple assignment operations, 100 events are consumed, there are still 100 events have not been consumed, at this time the wrap occurs, then it is not 1500-5000 times parkNanos (1L), this system switching is not 1500-5000 times parkNanos (1L), this system switching is not a good idea? ), is this system switching too consuming?On the contrary, if you use next(), then each time you judge for the next cursor position, you will wait for one consumption at most. So is it recommended to use the default next()? And next(n) hanging mechanism instead of simple parkNanos(1L), such as and n some kind of correlation, or to put the winding judgment to event fill to determine the sequence of each slot? (Of course, this change for the whole architecture is a big disruption)

ocoanet commented 2 months ago

A few thoughts:

chenggwang commented 2 months ago

A few thoughts:

  • A filled ring-buffer is an uncomfortable situation in the first place. The queueing will increase the event processing latency and the backpressure will probably negatively impact the producer performance. I am not sure it is worth optimizing batch publication for this scenario.
  • next(int n) is also used to claim a contiguous block of events. In this case, you cannot replace it by multiple calls to next().
  • Using next(int n) for performance is a good practice (even if you do not need contiguous events). If you fear to hit the ring-buffer capacity, you can simplify add a reasonable upper bound to n. "reasonable" is relative to you ring-buffer size of course.

OK!@ocoanet Thank you for your thoughts! I brought this up because I wanted everyone to discuss it. All can understand this framework design details more deeply in the discussion.A small request, by the way.@Palmr By the way a small request, can you mark my issues as questions?

Palmr commented 2 months ago

@swarren12 or @isolgpus will have to assist with changing issue types.

Earlier this year I left LMAX and therefore handed back my owner rights for this repo.