tag:blogger.com,1999:blog-5171098727364395242.post7843110683196822070..comments2023-05-14T13:23:31.669+01:00Comments on Psychosomatic, Lobotomy, Saw: Picking the 2013 SPSC queue champion: benchmarking woesNitsanhttp://www.blogger.com/profile/10496299147100350513noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-5171098727364395242.post-6649579579048457372015-12-14T15:45:01.148+00:002015-12-14T15:45:01.148+00:00Sorry markus, I don't have allot of time on my...Sorry markus, I don't have allot of time on my hands at the moment. I would be easier for me to review the code if you posted it a a compilable java class somewhere...Nitsanhttps://www.blogger.com/profile/10496299147100350513noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-20133510294583019592015-12-04T15:37:52.176+00:002015-12-04T15:37:52.176+00:00Note: by removing some asserts some little mistake...Note: by removing some asserts some little mistake has sliped in<br />if(tail - head++) == buffer.length && parked != null)<br />should be:<br />if((tail - head++) == buffer.length && parked != null)<br /><br />it was:<br />head++;<br />if(parked != null){<br />assert((tail - (head-1)) == buffer.length)<br />...<br /><br />but i changed it in both methods, because i thought it should be more clear, but because parked only get seted when (tail - head++) == buffer.length and after that producer stops doing anything until schedule() is called: (tail - head++) == buffer.length should hold always.<br /><br />and I overlooked the line: if(profiler != null)profiler.profileReceive(); which should be removed, as you see i tried to simplyfy so no unecessery stuff is theire, but i failed in my hurryAnonymoushttps://www.blogger.com/profile/11433076365891249008noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-44732798958285199822015-12-04T15:35:57.447+00:002015-12-04T15:35:57.447+00:00This comment has been removed by the author.Anonymoushttps://www.blogger.com/profile/11433076365891249008noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-80280828070500315412015-12-04T15:24:24.066+00:002015-12-04T15:24:24.066+00:00Because I failed, I currently falled back to a syn...Because I failed, I currently falled back to a synchronized variant so i can continue, no i want to make it faster :).<br />Important is, that the runnable I schedule is the other side of the queue, which stopped when they set the runnable.<br /><br />That is what i currently have;<br /><br />public class SyncChannel implements Channel {<br /> private final int mask;<br /> private final Object[] buffer; //will be power of 2 in size<br /> private long tail = 0;<br /> private long head = 0;<br /> private Suspension parked;<br /><br /><br /> //max size will be power of 2 in size<br /> public SyncChannel(int maxSize){<br /> mask = maxSize - 1;<br /> buffer = new Object[maxSize];<br /> }<br /><br /> public synchronized boolean offer(Object t, Suspension susp) t{<br /><br /> if((tail - head) == buffer.length){<br /> parked = susp;<br /> return false; //suspended (Task will abort / and continue when susp.schedule() is called)<br /> }<br /> buffer[((int)tail) & mask] = t;<br /> if(tail++ == head && parked != null){<br /> Suspension s = parked;<br /> parked = null;<br /> s.schedule();<br /> }<br /> return true; //suceeded<br /> }<br /><br /> @Override<br /> public synchronized T poll(Suspension susp){<br /> if(tail == head){<br /> parked = susp;<br /> return null; //suspended (Task will abort / and continue when susp.schedule() is called)<br /> }<br /> if(profiler != null)profiler.profileReceive();<br /> T res = (T)buffer[((int)head) & mask];<br /> buffer[((int)head) & mask] = null;<br /> if(tail - head++) == buffer.length && parked != null){<br /> Suspension s = parked;<br /> parked = null;<br /> s.schedule();<br /> }<br /> assert res != null;<br /> return res; //suceeded<br /><br /> }<br />}<br />Anonymoushttps://www.blogger.com/profile/11433076365891249008noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-36324463364280157632015-12-04T15:08:35.476+00:002015-12-04T15:08:35.476+00:00I'm not sure I'm getting your requirement ...I'm not sure I'm getting your requirement correctly:<br />- On offer/poll you want to detect transition from empty/full. If the transition is detected you will schedule a runnable somewhere. The queues currently do not detect this transition. Detecting it is not hard in the SPSC case at least.<br />- Only one side can have a 'continuation' is stored. This sounds like a CAS.<br />Send me your code and I'll see if I can helpNitsanhttps://www.blogger.com/profile/10496299147100350513noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-27740642149409168762015-12-04T14:49:01.971+00:002015-12-04T14:49:01.971+00:00First of All Great work, I really enjoing reading ...First of All Great work, I really enjoing reading it.<br />I didn't now where exactly to ask this Question to you, so I try it here in the comments.<br /><br />For a Project of mine I'm in the need of a really Fast SPSC Queue, maybe later a MPSC Queue too.<br />Sadly I have some additional requirements, so I can not use your Queues without modification.<br />As hard as I tried, I could not find a solution, so I hope you will have one.<br /><br />To my Requirements:<br />my offer & poll methods take an adidtional Parameter which represents a Continuation.<br />In the case where the offer or poll fails because the queue was empty or full, I want to store the continuation to a field in the queue and as soon as an element is added or removed, the Continuation.shedule function should be called (which schedules the continuation into a ForkJoinPool) and then the continuation should be removed from the queue. <br /><br />I have to guarantee, that never both sides have saved theire continuation into the queue (one get lost, because theire is only one field to store it) and that whenever the queue is nonfull and nonempty no continuation is stored.<br /><br />In all may attempts i often ended up in the situation where theire where elements in the queue but the reader was suspended (put their suspension into the field but schedule was never called) and the writer has already produced his whole workload but failed to call schedule.<br /><br />Any idea how to design a Fast SPSC Queue with Suspension?<br /><br />Anonymoushttps://www.blogger.com/profile/11433076365891249008noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-82454190277185421992015-02-04T11:49:41.226+00:002015-02-04T11:49:41.226+00:00Thanks for pointing it out, fixed all the source l...Thanks for pointing it out, fixed all the source links. JAQ is now JCTools and some queues have been renamed and reshuffled...<br />Let me know if you find more broken links.Nitsanhttps://www.blogger.com/profile/10496299147100350513noreply@blogger.comtag:blogger.com,1999:blog-5171098727364395242.post-27240965392235790222015-02-03T17:29:06.266+00:002015-02-03T17:29:06.266+00:00Thanks Nitsan for the great posts in this series.
...Thanks Nitsan for the great posts in this series.<br />The link to the "winner" (FF2) is broken. Is the class available on GIT or somewhere else?Amirnoreply@blogger.com