Archived

This topic is now archived and is closed to further replies.

Is 32 threads to many?

This topic is 4956 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

If you''ve read any of my other questoins, you may know that i''m working with a custom piece of software that utalizes the serial port. The hardware is very slow. If I leave the serial comm code on the same thread as the GUI, then there are large parts of time where the GUI is useless because the code is pulling data off of the board. To fix this porblem, I simply create a worker thread to handle reading data off of the board. Now, to further the troubles, I''m supose to pull the data off of the board every 30 seconds. This isn''t a problem for a few boards; however, the could be up to 32 boards connected to a single computer and at times, it can take up to a second to pole a board for it''s data. Clearly 32 boards X 1 second of time for data access is greater then the 30 second window I have to pull data. Pulling the data is not CPU instensive, it''s just slow and a lot of waiting on hardware. Would it be alright to spawn a thread for each board and have a possiblity of up to 32 threads? Or should I use more like a thread pool with, say, eight boards per thread? Just looking for opinions. The software runs on windows xp and is written in C# (.Net). thanks for any feedback

Share this post


Link to post
Share on other sites
You might be able to simply use overlapped I/O. If you''re accessing the serial port using CreateFile, ReadFile, etc., then you can create the file as overlapped (one of the flags somewhere), and then it will run in the background; Windows handles the "threading" on its own. I don''t really think it actually spawns an entire thread for each overlapped read call, but it works about the same. Then you would just call WaitForMultipleObjects, using an array with all of your hEvent handles (from the OVERLAPPED structure). Whenever any of the ports had any activity, your Wait call would return, and you could find out which one(s) is active, handle whatever you need to handle, and then wait again until more activity occurs.

However, if you just stick with your current model, considering this stuff occurs within a timeframe of seconds, not milliseconds or microseconds, I can pretty much guarantee you that 32 threads is going to have no significant impact on performance, unless you thoroughly screw up your management of them somewhere.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Mike
If you''ve read any of my other questoins, you may know that i''m working with a custom piece of software that utalizes the serial port. The hardware is very slow.

If I leave the serial comm code on the same thread as the GUI, then there are large parts of time where the GUI is useless because the code is pulling data off of the board. To fix this porblem, I simply create a worker thread to handle reading data off of the board.

Now, to further the troubles, I''m supose to pull the data off of the board every 30 seconds. This isn''t a problem for a few boards; however, the could be up to 32 boards connected to a single computer and at times, it can take up to a second to pole a board for it''s data. Clearly 32 boards X 1 second of time for data access is greater then the 30 second window I have to pull data.

Pulling the data is not CPU instensive, it''s just slow and a lot of waiting on hardware. Would it be alright to spawn a thread for each board and have a possiblity of up to 32 threads? Or should I use more like a thread pool with, say, eight boards per thread?

Just looking for opinions. The software runs on windows xp and is written in C# (.Net). thanks for any feedback


Since you''re writing this on winxp/c# I assume "every 30 seconds" isn''t a hard RT requirement. Where is your bottleneck? Transferring data over serial(in which case you might consider a faster interface than rs-232) or is that 1 second spent mostly waiting for the board to collect data w/ little traffic over serial?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Magmai Kai Holmlor
How are you going to place 32 comports in the PC?



It''s possible, I''ve crammed many com ports onto pc hardware before. But never with windows though, that''ll be interesting. You just get 4 PCI cards with 8 serial ports/card. And you have to get cards that support IRQ sharing, because otherwise you''re screwed.

Share this post


Link to post
Share on other sites
There are plenty of devices that allow lots of comm ports. I''ve used one that was an external box with 8 ports on it that you could chain together to get 256 ports running off 1 card.

Share this post


Link to post
Share on other sites
I don''t see how it would take 1 second to pull data off of each port, assuming there''s buffering on the card. While you''re reading from one card, the buffer will fill on the other cards, so reading from those cards will be fast once you get to them.

If the card is truly ancient, and only has lik 8 bytes of buffering, then you need to read in non-blocking mode, meaning you don''t read more data than what''s there; do your own buffering, and round-robin between the cards. Once there is enough data in the buffer for one of the cards, do what you need to do with it, clear the buffer, and continue.

Overlapped I/O is one way of getting non-blocking I/O on Windows.

Share this post


Link to post
Share on other sites
Check out IOCP. IOCP can literally manage thousands of OVERLAPPED I/O handles per processors. Now if you had multiple processors, you can process double the count.

32 threads count is no problem.

Kuphryn

Share this post


Link to post
Share on other sites
I would use a single worker thread and async / overlapped IO. IO control ports are probably overkill.

32 threads will work but it's wasteful and might make debugging more difficult. The code will probably be simpler though.

(actually with overlapped IO even the worker thread is probably unnecessary...)

[edited by - Anon Mike on May 20, 2004 1:42:38 PM]

Share this post


Link to post
Share on other sites
There's nothing wrong with 32 threads as long as there's not busy waiting. But if you have just a little busy waiting, you're gonna be multiplying that by 32, so make sure your thread is well designed. To me, this could be a good example of when multithreading can simplify a program.


[edited by - kdogg on May 20, 2004 9:42:57 PM]

Share this post


Link to post
Share on other sites
If you are using some sort of multi I/O board with many serial ports, odds are the board buffers quite a bit of data anyway, so it''s not like you need to sit there waiting for each bit on each port.

I bet you could probably just poll and get fine results even without a single thread.

Share this post


Link to post
Share on other sites
Polling increases the latency of your system.
If you poll every 10ms, you''ll respond on average after 5ms. If you are trying to move lots of data over a slow line, this latency will kill you. With blocking IO or asycronous IO, you can respond within microseconds.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ppl answering "32 threads is nothing" clearly don''t come from the server-side world. A design using 32 threads really frightens me, both from performance and complexity reason. It''s ceraintly a strongly discouraged method on Windows. I/O completion port on the other hand is the recommended method.

As you''re using C#, async read and write is the way to go, that will benefit from i/o completion ports.

Share this post


Link to post
Share on other sites
What is the board you are programming? It''s kind of hard to say what is the best approach, you should RTFM and find out what capabilities it has and if there might be a better solution designed into it.

32 threads is kind of excessive I think, but that''s me.

Peace

Share this post


Link to post
Share on other sites
First, to clear up some confusion, the hardware is custom made and was designed in the early eighties. The board doesn''t buffer anything at all.

The software I write has got to be able to sit there and wait for data to come and buffer it on it''s own. If the data does not come, I can''t sit there and wait forever. After a few attempts at getting the data, if it still fails, I need to request the data again.

For those of you that cannot believe that it takes a second to get the data off of the board.... it does. I''ve tried speeding my reads from the board up, but if i go any faster, there is no data there to be read and I just have to wait until there is. I''m using Portmon to view the data on the port and there really isn''t anything there to be read. It just doesn''t go any faster than a second (actually, about 1.276 seconds).

I''m looking into the overlapped and async i/o, but I don''t really know much about it, so I can''t say if it''s helping yet or not.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Slow acccess doesn''t surprise me. Given that the h/w acts as a serial port per board

Your problem is similar to normal socket connections where the protocol wants you to send keep-alives if nothing has been transfered for X seconds.

It seems like you''re thinking that your solution must be to abort the read if a timeout occurrs. I''m not sure that''s the case.

Consider having a timestamp for "LastReceivedData" that you maintain for each port. Whenever your read-callback returns, just update that timestamp (to prevent timeout).

Then you have a separate timer (System.Threading.Timer or System.Timers.Timer) that every 5 second or so looks at all timestamps (you probably keep them in an array) to see if there are timeouts. For all ports where there have been a timeout, simply issue the request again. Your pending read does not need to return until there actually is data to read. If there have been timeouts in between causing new requests isn''t really interesting for your read-callback.


Another thing. How do you open the port? Don''t remember if you actually can use serial ports directly in 1.1 framework, or if you call CreateFile yourself. In any case, you could (as an alternative to the timestamps I suggested above) set a read-timeout on the serial port, and then your callback would return with 0 bytes to read. If that happens you know it''s because of a timeout, and you can issue the request again.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Anonymous Poster
Given that the h/w acts as a serial port per board...

(forgot to complete the sentence)

...it seems like PeterTarkus'' suggestion (rtfm) won''t help you. I think you''re on the right track. Now you need to decide whether to design using the traditional *nix-way, with one thread per request, or the Windows-way using async I/O and I/O completion ports.

Share this post


Link to post
Share on other sites