<div dir="ltr"><br>Hi Jason and others,<br><br>I am trying to implement the load balancing pattern idea. First I just would like to make "lbbroker: Load-balancing broker in C" code from the Guide to work on Windows 64 with VC2010.<br>
<br>All that I changed in it was creating the threads using Windows like this:<br><br>int client_nbr;<br>for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++) <br>{<br>HANDLE localHandle = (HANDLE) _beginthreadex(NULL, 0, client_task, NULL, 0, NULL);<br>
<br>}<br>int worker_nbr;<br>for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++) <br>{<br>HANDLE localHandle = (HANDLE) _beginthreadex(NULL, 0, worker_task, NULL, 0, NULL);<br><br><div>}</div><div><br></div><div>
For some reason in hangs in select() in zmq_poll() .</div><div><br></div><div>What can be the reason for that?</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Feb 3, 2013 at 5:44 PM, dan smith <span dir="ltr"><<a href="mailto:dan25311@gmail.com" target="_blank">dan25311@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div>Hi Jason and others,</div><div><br></div><div>I am trying to implement the load balancing pattern idea. First I just would like to make "lbbroker: Load-balancing broker in C" code from the Guide to work on Windows 64.</div>

<div><br></div><div>All that I changed in it was creating the threads using Windows like this:</div><div><br></div><div>int client_nbr;<br> for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++) <br>      {<br>             HANDLE localHandle = (HANDLE) _beginthreadex(NULL, 0, client_task, NULL, 0, NULL);<br>

<br>      }<br>     int worker_nbr;<br>       for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++) <br>      {<br>             HANDLE localHandle = (HANDLE) _beginthreadex(NULL, 0, worker_task, NULL, 0, NULL);<br><br>  }</div><div><br></div>
</div><div class="HOEnZb"><div class="h5">
<div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 29, 2013 at 9:06 AM, dan smith <span dir="ltr"><<a href="mailto:dan25311@gmail.com" target="_blank">dan25311@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div dir="ltr"><div>Jason,</div><div><br></div><div>Thanks for the suggestion. I will apply the lbb broker pattern right away to that problem and will share the results. To me it is a good news that this is a design issue...</div>

<span><font color="#888888">
<div><br></div><div>Dan</div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 29, 2013 at 12:58 AM, Jason Smith <span dir="ltr"><<a href="mailto:jason.nevar.smith@gmail.com" target="_blank">jason.nevar.smith@gmail.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Dan, <div><br></div><div>I have found the issue with the processing times. </div><div><br></div><div>


<pre style="font-family:'Courier New';color:rgb(212,212,212);background-color:rgb(32,32,32)"><div>
        <span style="color:rgb(255,136,17)">for</span><span style="color:silver">(</span><span style="color:rgb(196,196,196)">iequation</span> <span style="color:silver">=</span> 0 <span style="color:silver">;</span> <span style="color:rgb(196,196,196)">iequation</span> <span style="color:silver"><</span> <span style="color:rgb(196,196,196)">nequation</span> <span style="color:silver">;</span> <span style="color:rgb(196,196,196)">iequation</span><span style="color:silver">++)</span>    
        <span style="color:silver">{</span>
                <span style="color:rgb(196,196,196)">zmq_msg_t</span> <span style="color:rgb(196,196,196)">msg</span><span style="color:silver">;</span>
                <span style="color:rgb(196,196,196)">rc</span> <span style="color:silver">=</span> <span style="color:rgb(196,196,196)">zmq_msg_init</span> <span style="color:silver">(&</span><span style="color:rgb(196,196,196)">msg</span><span style="color:silver">);</span>
                <span style="color:rgb(196,196,196)">rc</span> <span style="color:silver">=</span> <span style="color:rgb(196,196,196)">zmq_msg_init_size</span><span style="color:silver">(&</span><span style="color:rgb(196,196,196)">msg</span><span style="color:silver">,</span> 8<span style="color:silver">);</span>
                <span style="color:rgb(196,196,196)">memset</span> <span style="color:silver">(</span><span style="color:rgb(196,196,196)">zmq_msg_data</span> <span style="color:silver">(&</span><span style="color:rgb(196,196,196)">msg</span><span style="color:silver">),</span> <span style="color:rgb(250,128,114)">'A'</span><span style="color:silver">,</span> 8<span style="color:silver">);</span></div>



                <span style="color:rgb(196,196,196)">ithread</span> <span style="color:silver">=</span> <span style="color:rgb(196,196,196)">messageCounter</span> <span style="color:silver">%</span> <span style="color:rgb(196,196,196)">nthread</span> <span style="color:silver">;  <---- RIGHT HERE</span><div>



                <span style="color:rgb(196,196,196)">messageCounter</span><span style="color:silver">++</span> <span style="color:silver">;</span>
                <span style="color:rgb(255,136,17)">void</span> <span style="color:silver">*</span> <span style="color:rgb(196,196,196)">socket</span> <span style="color:silver">=</span> <span style="color:rgb(196,196,196)">socketsSend</span><span style="color:silver">[</span><span style="color:rgb(196,196,196)">ithread</span><span style="color:silver">];</span>
                <span style="color:rgb(196,196,196)">rc</span> <span style="color:silver">=</span> <span style="color:rgb(196,196,196)">zmq_sendmsg</span> <span style="color:silver">(</span><span style="color:rgb(196,196,196)">socket</span><span style="color:silver">,</span> <span style="color:silver">&</span><span style="color:rgb(196,196,196)">msg</span><span style="color:silver">,</span> 0<span style="color:silver">);</span>
                <span style="color:rgb(196,196,196)">zmq_msg_close</span><span style="color:silver">(&</span><span style="color:rgb(196,196,196)">msg</span><span style="color:silver">);</span>
        <span style="color:silver">}</span>
</div></pre></div><div>The code above doesn't take into account time it takes for the passed equation. It treats them all as being of equal "work" which they don't appear to be. This means that some threads will sit around waiting for a very long time while others are still busy with three or four items on their queue. </div>



<div><br></div><div>This is where a load balancing pattern would be very handy. Search for the line with "<a style="font-size:13px;color:rgb(160,32,32);text-decoration:initial;font-family:verdana,arial,helvetica,sans-serif">lbbroker: Load-balancing broker in C</a>" in the zguide for an explanation and example code. (<a href="http://zguide.zeromq.org/page:all" target="_blank">http://zguide.zeromq.org/page:all</a>). </div>



<div><br></div><div>The short of it is, have your application have a req socket in it. Send on that req socket to a router (frontend) in another thread. All this threads job is to do is work out which thread is not busy (first in the list if need be) and then route the packet to that thread. This is done through another router (backend) socket connected to each "Worker" thread that you currently have. These then do the work and message back the result to the router (backend) which then knows it can pass the result all the way back to the requesting "client" (frontend). The reason for the second thread to determine where the work has to be sent is because you won't know until its being worked on how long something will take in this case. Predetermining this is causing the issues with regards to only a 3 to 5 times speed up on my machine. </div>



<div><br></div><div>The zguide has a wonderful diagram of this. Its very simplistic and doesn't handle crashes, or overloading, etc. These would have to be worked into the end solution based on your environments needs. </div>



<div><br></div><div>If I get a chance tonight I might knock something up using your example. Depends on how much packing I get done, haha. </div><div><br></div><div>The way I found this was the issue is simply counting the time each thread was "waiting" and "processing" found that some were super busy processing while others were just sitting around. So you guess was right about the sockets just sitting there in some threads. The time being "wasted" however is sadly a design issue at this point, not so much ZeroMQ ;)</div>



<div><br></div><div>Hope that helps. </div><div><br></div><div>Lastly as a bonus, this load balancing pattern means you would be able to add as many front ends and back-ends as you saw fit. Only the "balancer" is static in this design.</div>


<span><font color="#888888">
<div><br></div><div>- J</div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On 29 January 2013 16:30, dan smith <span dir="ltr"><<a href="mailto:dan25311@gmail.com" target="_blank">dan25311@gmail.com</a>></span> wrote:<br>



<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div>Hi Jason,</div><div><br></div><div>Thanks a lot for devoting your time to my problem. My expertise is negligible in this area.</div>



<div><br></div><div>Looks like that symptom might be CPU dependent ? I tried it just on a quad-core laptop, it has 16G memory though.</div>
<div><br></div><div>This problem is really important so I started to evaluate alternative solutions. I found lock-free queues , more specifically lock-free single-producer - single-consumer circular queues. I was impressed by the latency: I could send 10 000 000 (ten millions) 8 bytes messages in one  second. It is a very simple thing , there are many versions of it. Latency is in the 100 nanoseconds range. I do not know the reasons but looks like it is faster for this kind of communication.</div>




<div><br></div><div>Using it I could reach 30 % speedup for the real problem so the parallel version is faster by now at least, still not fast enough though...</div><div><br></div><div>Now the problem is how to notify quickly the threads that data is coming.</div>




<div><br></div><div>I will test both solutions on a better machine with more cores. Maybe if we have got just few messages, they spend some time in a cache or something. If this is the case, is there a way to forward them to the CPU more quickly? Any further input will be appreciated.</div>




<div><br></div><div>Thank you again,</div><div><br></div><div>Dan</div><div><div><div><br></div><div><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jan 28, 2013 at 6:26 PM, Jason Smith <span dir="ltr"><<a href="mailto:jason.nevar.smith@gmail.com" target="_blank">jason.nevar.smith@gmail.com</a>></span> wrote:<br>




<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Dan, <div><br></div><div>Just tested the debug version and it does drop but not as much as you listed. Also of note I have been testing on 64 bit windows 7, i7-2600 with a large amount of Ram. The next test for me will be to look at where the time is taken up, however thought I would report on what I have seen so far. </div>




<span><font color="#888888">
<div><br></div><div>- J </div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On 29 January 2013 11:16, Jason Smith <span dir="ltr"><<a href="mailto:jason.nevar.smith@gmail.com" target="_blank">jason.nevar.smith@gmail.com</a>></span> wrote:<br>





<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Dan, <div><br></div><div>Here's something I have found with your code. Testing here I see the same speed up for all numbers of equations. I am using the release version of the dll however. About to test the debug version of the dll to see if I get different behaviour. </div>





<span><font color="#888888">
<div><br></div><div>- J</div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On 23 January 2013 13:56, dan smith <span dir="ltr"><<a href="mailto:dan25311@gmail.com" target="_blank">dan25311@gmail.com</a>></span> wrote:<br>






<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Jason,<br></div><div><br></div><div>Thanks a lot for taking a look at it.</div><div><br></div><div>






As for the "while(nfinish > 0" loop, my experience is that it does not have significant effect on the time. If I remove it and allow the threads to die, the difference is negligible. In the real application the threads needs to remain alive of course, I just tried to check that the thread closing is not the reason. </div>







<div><br></div><div>Closing the sockets in threads might not be the reason either, a terminating message is sent back to the main thread before that.</div><div><br></div><div>I use zeromq-3.2.2.  </div><div><br></div><div>







In the real application I am sending a pointer, here the 8 As simulate that.</div><div><br></div><div>I am looking forward to your further comments very much. Hope that I am the one who made some mistake and there is a solution for sending few small messages at the latency that I measured for large number of messages (that was under 1 microseconds which would be cool)</div>







</div><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div>On Tue, Jan 22, 2013 at 8:13 PM, Jason Smith <span dir="ltr"><<a href="mailto:jason.nevar.smith@gmail.com" target="_blank">jason.nevar.smith@gmail.com</a>></span> wrote:<br>







</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On 23 January 2013 11:42, dan smith <span dir="ltr"><<a href="mailto:dan25311@gmail.com" target="_blank">dan25311@gmail.com</a>></span> wrote:<br>








<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">while(nfinish > 0)</blockquote></div><div class="gmail_extra">








<br></div><div class="gmail_extra">Haven't had a chance to compile this here. For some reason have a linker issue on my work machine. </div><br>At first glance the "<span style="font-family:arial,sans-serif;font-size:13px">while(nfinish > 0)" loop assumes sequential thread </span><span style="font-family:arial,sans-serif;font-size:13px">completion </span><span style="font-family:arial,sans-serif;font-size:13px">for best time. For example you only know of thread 7 finishing only until 1 through to 6 have completed. Don't know if this is affecting things drastically or not. Maybe switching to polling here and updating a "completed" vector list might work better.</span></div>








<div class="gmail_extra"><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div class="gmail_extra"><span style="font-family:arial,sans-serif;font-size:13px">Another area I would look into is the linger of the sockets, it shouldn't affect closing them down within the thread however its something to consider. </span></div>








<div class="gmail_extra"><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div class="gmail_extra"><font face="arial, sans-serif">When I get a chance I would be looking to place more asserts in to make sure messages were doing what I thought they were (send and receive calls return values). Then I would be checking the timing of any close down code. </font></div>








<div class="gmail_extra"><font face="arial, sans-serif"><br></font></div><div class="gmail_extra"><font face="arial, sans-serif">Hope this helps in the meantime. </font></div><div class="gmail_extra"><br>
</div></div>
<br></div></div><div>_______________________________________________<br>
zeromq-dev mailing list<br>
<a href="mailto:zeromq-dev@lists.zeromq.org" target="_blank">zeromq-dev@lists.zeromq.org</a><br>
<a href="http://lists.zeromq.org/mailman/listinfo/zeromq-dev" target="_blank">http://lists.zeromq.org/mailman/listinfo/zeromq-dev</a><br>
<br></div></blockquote></div><br></div>
<br>_______________________________________________<br>
zeromq-dev mailing list<br>
<a href="mailto:zeromq-dev@lists.zeromq.org" target="_blank">zeromq-dev@lists.zeromq.org</a><br>
<a href="http://lists.zeromq.org/mailman/listinfo/zeromq-dev" target="_blank">http://lists.zeromq.org/mailman/listinfo/zeromq-dev</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
zeromq-dev mailing list<br>
<a href="mailto:zeromq-dev@lists.zeromq.org" target="_blank">zeromq-dev@lists.zeromq.org</a><br>
<a href="http://lists.zeromq.org/mailman/listinfo/zeromq-dev" target="_blank">http://lists.zeromq.org/mailman/listinfo/zeromq-dev</a><br>
<br></blockquote></div><br></div></div></div></div>
<br>_______________________________________________<br>
zeromq-dev mailing list<br>
<a href="mailto:zeromq-dev@lists.zeromq.org" target="_blank">zeromq-dev@lists.zeromq.org</a><br>
<a href="http://lists.zeromq.org/mailman/listinfo/zeromq-dev" target="_blank">http://lists.zeromq.org/mailman/listinfo/zeromq-dev</a><br>
<br></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
zeromq-dev mailing list<br>
<a href="mailto:zeromq-dev@lists.zeromq.org" target="_blank">zeromq-dev@lists.zeromq.org</a><br>
<a href="http://lists.zeromq.org/mailman/listinfo/zeromq-dev" target="_blank">http://lists.zeromq.org/mailman/listinfo/zeromq-dev</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>