|
-
Apr 15th, 2010, 02:33 AM
#1
Thread Starter
Junior Member
[RESOLVED] GDI functions are slowing down Winsock
Hello,
I'm not sure if this is in the correct area, so I apologize if it is wrong. But here is my scenario. I wrote a program that plots data in real-time. Once an X-Y value is calculated it is plotted onto a PictureBox, then the value is sent over Winsock to a remote location.
===== Pseudo Code (server) ======
Calculate value
FillRect PictureBox.hWnd 'Clear image
MoveTo X0,Y0
LineTo Xn,Yn 'Repeat if needed
InvalidateRect PictureBox.hWnd
Winsock.SendData Xn-Yn
DoEvents 'May be repeated several times, or just once
'Repeat the process all over again, continuously
=============================
Now, the client code is able to accept the data with GetData and plot it on it's end with no problems. So here is my big problem, if I comment out the InvalidateRect line of my server code I get a really, really, fast data transfer across the client/server. This fast transfer is what I want. If I leave in the InvalidateRect then the transfer runs at about 1/3 of the speed.
I've tried PictureBox.Refresh and UpdateWindow. InvalidateRect seems to allow for Winsock.SendData to work the fastest. But with this line commented out the PictureBox never updates its display (screen) on the server side. How can I get the display to update without having the network card, or Winsock, reach an internal timeout that simply sends the little data that is in the buffer? Or, is there a faster/better method then InvalidateRect? One way I could fix this is to have an internal count of data points and internal timeout, e.g.:
If( (GetTickCount() - lLastCount > 50 ms) or nPointCount > 5 ) Then Winsock.SendData
But I am hoping to not do this, I am trying to find a more elegant API method for the GDI issue.
Please help, I am very stumped.
Thank you and sorry for the long message.
-
Apr 15th, 2010, 06:49 AM
#2
Re: GDI functions are slowing down Winsock
Welcome to VBForums
What are you using, VB6 or at .Net version?
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Apr 15th, 2010, 08:34 AM
#3
Re: GDI functions are slowing down Winsock
How much of the window are you invalidating? By creating a bounding rect as small as possible that encompasses just the area that needs to be redrawn will speed things up.
Faster than invalidaterect?
The issue isn't the API, it is either you are "refreshing" more picturebox than needed, or "refreshing" too often. The question you may need to ask yourself is, "does the graph have to be updated real time?" If the answer is no, then update the graph on a timer. Use a "dirty" flag to indicate the data changed, so the timer event doesn't update the graph if there isn't anything to update (again wasting cpu cycles).
The above is just one idea. Sounds like your graph may be quite large? Please respond to opus' question also.
Edited: also look at your drawing routine; optimize it to death. Example: if the graph scrolls, don't erase & redraw all the points over and over again, slide what doesn't change by using BitBlt.
Last edited by LaVolpe; Apr 15th, 2010 at 08:51 AM.
-
Apr 15th, 2010, 09:16 AM
#4
Re: GDI functions are slowing down Winsock
 Originally Posted by LaVolpe
if the graph scrolls, don't erase & redraw all the points over and over again, slide what doesn't change by using BitBlt.
Uwgrad
As an alternative to LaVolpe's method to deal with scrolling, you could
use a PictureBox-in-a-PictureBox. The outer PB would be a mask, to set
the "viewing" area. The inner PB would be the entire scope of the graph,
and could be "moved around" by setting it's Top and Left properties.
Nothing would need to be redrawn.
Spoo
-
Apr 15th, 2010, 09:33 AM
#5
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
The graph does not scroll, it is a real-time X-Y scatter graph that is always in the "zoom to fit window" state. So it does need to be redrawn (if a new point lies outside of the window) or simply a new line added (if a new point lies inside of the window).
The drawing algorithm is storage mechanism I use are fast, if I don't have a Winsock connection (or no users connected) the graph can do real-time updates of a lot of data with no flicker or slow down. So the Winsock thing has me confused because I thought SendData was asynchronous.
-
Apr 15th, 2010, 09:34 AM
#6
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
 Originally Posted by opus
Welcome to VBForums
What are you using, VB6 or at .Net version?
Sorry, VB6; with SP6.
-
Apr 15th, 2010, 09:42 AM
#7
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
Thank you everyone for your input. I only want the graph in real-time because other users in the lab refer this. I have optimized the heck out of the drawing routines and got a 300% speed increase thus far. The routines work blazing fast, it's just the Winsock.SendData that slows down. I do need to redraw the entire PictureBox. It is a X-Y scatter graph and if the new data point lies outside of the PictureBox then I need to recalculate and redraw the entire graph. My graph is always in the "zoom to fit window" state. If the newly added data point is inside of the PictureBox, then I simply add that one point and don't need to redraw the graph. I use InvalidteRect so the PictureBox refreses, otherwise nothing will appear.
Sorry if this info is repetitive.
-
Apr 15th, 2010, 10:21 AM
#8
Re: GDI functions are slowing down Winsock
You can use a timing function before and after your SendData calls and also before and after your drawing routine to see how much time it really is taking to return. If your numbers are larger than you'd expect, then you know it is a bottleneck. If not, the bottleneck may be elsewhere. At least you'd know for sure.
Is this graph really large, like full screen?
Another option, though it may be a major overhaul would be to run 2 apps (i.e., two processes). One for the graphics and one for the data. They could use mapped files or shared memory to pass data to/from and/or PostMessage API to communicate. PostMessage is non-blocking and doesn't wait for destination to process where SendMessage does. This would be a last resort I would think.
-
Apr 15th, 2010, 11:10 AM
#9
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
The bottleneck is the InvalidateRect API, if I comment out that one line then the data transfer is really fast; I've tested many different scenarios and narrowed it down to that one line. The graph can be what ever size it wants to, small, full screen, etc. It resizes as the user resizes the window it is on.
I'm assuming when Windows updates the screen, hardware, it figures since it is doing hardware stuff why not finally send out what ever is in the Send Queue for the network card; even if it is really small. Besides, isn't Winsock.SendData suppose to asynchronous and the data is sent on its own thread (separate from mine)? If I don't comment out the InvalidateRect API on the server side I get only a few data points a second being transferred. If I comment it out then I get a lot more. I think it may be do to Windows doing some hardware updates and the TCP/IP overhead of the small packet size of a few data points is chewing up the bandwidth.
Who knows, if there are more ideas I would like to know and I'll look into the above comments.
Thank you
-
Apr 15th, 2010, 11:22 AM
#10
Re: GDI functions are slowing down Winsock
Well InvalidateRect isn't so much the issue as is updating the graphics. Whether RedrawWindow, InvalidateRect, UpdateWindow, or .Refresh is used, all should have similar unwanted effect.
Though Winsock SendData is async (from what I read about it), that doesn't necessarily mean it returns immediately. For example, VB usercontrol's .AsyncRead method is also async, except when the target exists on the system. I don't know what the rules are for Winsock, when it decides to return. Keep this thread open though, there are some good comm people that frequent here.
-
Apr 15th, 2010, 11:27 AM
#11
Re: GDI functions are slowing down Winsock
UW
I'm not familiar with InvalidateRect API, but if I understand you properly,
you only issue this when you need to refresh the PictureBox (ie, if datapoint
is beyond current graph extremes).
If this is correct, do you by any chance know in advance what the min and/or
max values of x and y will be? If so, perhaps as a test, you could simply
omit the "zoom to fit" feature.. just see if you can populate the graph with
all pieces of data. If that works, we can move on to the "next step."
Spoo
-
Apr 15th, 2010, 11:59 AM
#12
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
I need to refresh the graph always, even if the data point is with in the PictureBox. This is needed because the PictureBox will not update on its own with GDI functions, you have to tell it to refresh the hardware (screen). InvalidateRect simply tells the OS "When you get the time, write/update the screen for the user." As oppose to PictureBox.Refresh which forces Windows to update immediately; this is what was explained to me. I will not know the values ahead of time. This software communicates with equipment in the lab and plots the data returned from the experiment. I've implemented the:
If( GetTickCount - lLastCount > TimeOut OR nPoints > MaxPoints) Then SendData
See previous post. I'll let you guys know how well it worked, or failed, once I test it.
-
Apr 15th, 2010, 12:10 PM
#13
Re: GDI functions are slowing down Winsock
 Originally Posted by UWGRAD
I need to refresh the graph always, even if the data point is with in the PictureBox. This is needed because the PictureBox will not update on its own with GDI functions, you have to tell it to refresh the hardware (screen).
Not necessarily true all the time. If the .AutoRedraw=False, it should update pretty much immediately (message queue size dependent), no need to invalidate. I might have it backwards regarding the AutoRedraw value, but you can quickly test this in a temp project.
Per MSDN documentation for WM_PAINT: The system sends this message when there are no other messages in the application's message queue.
The queue doesn't stay full very long unless the system/another window is flooding it.
Anyway, you said you have to Invalidate even if point is in the picturebox. But when you do this, is your invalidation rectangle only the size/position of that point? If not, do so and you should see some improvement. This is where I was attempting to go in post #3 above.
-
Apr 15th, 2010, 12:31 PM
#14
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
AutoRedraw = True for my PictureBox. I was going to implement the RECT area just to the bounds of the LineTo command so only a small portion got updated. But when the graph needs to be rescaled I have to update the whole RECT of the PictureBox. At least 50% of the time this may be the case:
Pseudo:
FillRect
MoveTo X0, Y0
LineTo X1, Y1
LineTo X2, Y2,
...
LineTo Xn, Yn
InvalidateRect
I plan on using your suggestion, but 50% of the time it will still maintain the slow speed.
-
Apr 15th, 2010, 12:41 PM
#15
Re: GDI functions are slowing down Winsock
 Originally Posted by UWGRAD
I plan on using your suggestion, but 50% of the time it will still maintain the slow speed.
Yes but 50% of the time it will be lightening fast. Take a simple point for example, say 2x2 pixels and a screen size of just 256x256. Updating just that point updates only 4 pixels vs 65,536 pixels for the entire window, for each new point drawn within the graph. I know that is oversimplification, but the savings are real.
Edited: Other optimizations, maybe, can be put into play. But that would require you to post your drawing routines and if you decide to do that, you might want to post that in the graphics section of the forum with a new topic title, like "Drawing Optimization Tips", for example.
Last edited by LaVolpe; Apr 15th, 2010 at 12:45 PM.
-
Apr 15th, 2010, 12:49 PM
#16
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
I like your suggestion, I will put it in once I get the chance and test it out. I'll let you know how it works.
Thank you.
-
Apr 15th, 2010, 12:55 PM
#17
Re: GDI functions are slowing down Winsock
FYI: Another optimization could be to undersize your "zoom" window by a fixed percentage, say 10%. By undersizing, I mean the window obviously stays the same size, but your zoom factor is reduced. So if zoom factor was 1:1, you treat it as 1:0.9. This would give you a 10% window-size buffer. The idea is that if points fall within that 10%, you won't have to completely redraw the graph because you can still plot them within the picturebox . And 10% is negotiable, maybe a larger percentage would work just fine; the larger the better, the less complete redraws. Depending on the window size, even a 2% or 5% increase can be dramatic regarding the overall number of extra pixels made available.
-
Apr 15th, 2010, 01:01 PM
#18
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
I've thought about doing that too. But the plot updates so quickly there is almost no need, I've spent 6 months on optimizing this. I will try your RECT suggestion, that should determine how fast it will speed it up. If that works then I will implement the 10%.
Thank you
-
Apr 15th, 2010, 01:08 PM
#19
Re: GDI functions are slowing down Winsock
Alright then. Oh, and whatever rectangle structure you use for InvalidateRect, use the same for FillRect; obviously you don't want one larger than the other.
Good luck. Hope you get some significant, overall improvement.
-
Apr 15th, 2010, 02:27 PM
#20
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
FillRect is only used to erase the PictureBox so I can redraw the recalculated plot. This API is much faster than PictureBox.Cls. When drawing a data point with in the PictureBox I don't use FillRect.
-
Apr 19th, 2010, 10:33 AM
#21
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
OK, I've implemented the InvalidateRect with the RECT structure only containing the area of the line/points that needed to be drawn. When doing a rigorous speed test it did improve the speed by about 5.5%; but sadly, it did not increase my network speed. I also implemented my solution of the data point count and timeout, this also did not speed things up. I'm stumped and I guess the software works well enough. I am still open to suggestions.
Thank you.
-
Apr 20th, 2010, 08:34 AM
#22
Re: GDI functions are slowing down Winsock
Wow, only a 5.5% improvement, I thought that limiting/reducing number of pixels redrawn would provide better overall results.
Well good luck, tweaking network settings/packet sizes/etc is out of my realm of experience. Hopefully those more knowledgeable will respond shortly.
-
Apr 20th, 2010, 09:33 AM
#23
Re: GDI functions are slowing down Winsock
UW
Given that you are disappointed with only a 5.5% improvement,
would it be useful/acceptable to think of a completely different
alternative, namely:
-- collect data in real-time,
-- then after data-stream has concluded, draw the chart.
Spoo
-
Apr 27th, 2010, 12:45 PM
#24
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
I don't know how long the user will be running their test for. Sometimes it takes several hours, so I have to draw and send in real-time.
-
May 4th, 2010, 11:36 AM
#25
Thread Starter
Junior Member
Re: GDI functions are slowing down Winsock
Found the issue. When I run the server from inside the school's network, the data transfer is extremely slow when sending to a remote location. So I tested it by running the server on my home PC and connecting in to it from school, the client at school receives data extremely fast. So it is an issue with the school's network such as firewalls, etc.
I would like to thank everyone for the help. The GDI function changes really did help speed things up on the drawing side.
-
May 4th, 2010, 12:25 PM
#26
Re: [RESOLVED] GDI functions are slowing down Winsock
Glad to hear it. So a 5.5% improvement at the school may translate to a significantly larger improvement over a less restrictive network? Good.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|