I have studied both of your example programs: ExBlock and ExThread. I think
the main difference in my application and yours is that I am using the
CommPortTriggerAvail and CommPortTriggerTimer events to trigger the exit
from my blocking routine. My blocking routine runs in the same thread as
the ApdComPort was created in (not the main VCL thread though). With the
AdPacket, you can use the SyncEvents parameter to force the events to fire
even though your thread with the AdPort is sleeping (or calling
WaitForSingleObject). The CommPortTriggerAvail and CommPortTriggerTimer
events won't fire while my thread is sleeping with a sleep(n) or
WaitForSingleObject(EventHandle,1000).
In my code example that I initially posted, I used the following to try and
wait for the events to fire:
Win32Check(WaitMessage). That seemed to kind of work but the communications
was much slower as I described. WaitMessage must not return as soon as the
events are fired.
I think the most efficient solution would be if ApdPort had some way to wake
up my thread when it needed to generate the events. I am just not sure how
to make this happen.
Thanks
Greg Dunn
Eagle Research Corp
304-757-6565 ext 117
"Paul Breneman [TPX]" <Paul.Brenema...@TPX.TurboPower.com> wrote
in message news:FT8zkXQs...@tpsmail01.turbopower.net...
> Paul Breneman [TPX] wrote:
>
> > In at least the ExBlock example there should be no Sleep or other delays
> > in the normal operation. There is a delay when closing the port. Most
> > of my data acquisition work is with real slow baud rates so I've not had
> > to do many actual efficiency measurements but I think the ExBlock
> > example should be about as good as you get with AsyncPro and Windows.
>
> I thought that I should also mention that you could tweak the thread
> priorities in the ExBlock example to get some improvement that way.
>
> --
> Regards,
> Paul Breneman [TPX]
> http://www.BrenemanLabs.com
>
> Those of us with [TPX] after our names are not TurboPower employees but
> a group of folks that have volunteered to assist TurboPower and help
> fellow users who have questions about the operation of the products.
>
--
Mike Welch (TurboPower Software)
God Bless America
"Gregory A. Dunn" <gr...@eagleresearchcorp.com> wrote in message
news:Ab4fb1Bs...@tpsmail01.turbopower.net...
> Hello,
>
> I have an application where I am using several ports simultaneously. Each
> port is running in a seperate thread. I am trying to optimize the
> application for performance and also CPU time required. Each port
supports
> a ACK/NAK protocol to communicate to our devices over RS232, modem,
TCP/IP,
> etc. I use the OnTriggerAvail and OnTriggerTimer events to collect
incoming
> characters and to provide timeouts to retry messages. The spot in my code
> that I would like to optimize is when I am waiting for a response froum
the
> remote device. The Events are used to trigger an exit from the wait loop.
> Here is what I have tried so far:
>
> This version is the best performance wise but the CPU time is 99-100%.
> Other programs still seem to have enogh processor time though (at least on
a
> 1.8GHz with Windows XP).
>
> while MessageNotReceived and NoReceiveMsgTimeout do begin
> SafeYield
> end;
>
>
> This version has good CPU time (< 1%) but the perfomace goes down by about
> 31%.
>
> while MessageNotReceived and NoReceiveMsgTimeout do begin
> if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
> SafeYield
> else
> Sleep(1);
> end;
>
>
> My goal would be to allow the threads to sleep but wake them as quickly as
> possible when data is available to the thread. I tried using the
following
> version. The CPU time was fine (< 1%) but the performance was even lower
> (about 31% lower than the first version).
>
> while MessageNotReceived and NoReceiveMsgTimeout do begin
> SafeYield;
> Win32Check(WaitMessage); // Put Tread to sleep until a message is
> received.
> end;
>
>
> Do you have any suggestions to make this code most efficient for
performance
> and CPU time? In version 1, with only SafeYield, the perfomance is bets.
> I seemed like other programs still ran fine on my 1.8 GHz with Windows XP.
> Would this version be ok to use. Is is a problem when the CPU time is
near
> 100% or does this just mean that the program will use it if its available.
> What CPU time should I shoot far for a nicely behaved program?
>
> Thanks,
> Greg Dunn
> Eagle Research Corporation
>
>
Thanks, for the response. I understand your suggestion but it does not fit
in with the way my code is structured. My code is written so that I can use
simple inline code (not assembly) to perform step by step communications
sequences. If the thread is completely event driven then I have to maintain
an extremely complex state machine. With the inline version, I only have
two places where I wait for something to complete: When I am waiting for a
received message and when I am waiting for a ACK after I send a message.
The example code I posted in the previous message implements these waiting
periods.
Thanks,
Greg Dunn
"Mike Welch [TurboPower Software]" <please@keep_it_in_the_newsgroup.thanks>
wrote in message news:yJaIDJCs...@tpsmail01.turbopower.net...
Thanks for the help. I will try using the methods you suggested. I am
currently using TAPI so I guess there may be more problems with that. I
will also be adding the Winsock support in the near future. I am currently
using TApdWinsock, but only as a standard Com port. I was hoping it would
be an easy modification down the road to add the winsock support, Oh well.
I sure would be nice if Turbopower would plan to add built in support for
all of these items. It seems like it would really improve an already great
product.
Thanks,
Greg
"Paul Breneman [TPX]" <Paul.Brenema...@TPX.TurboPower.com> wrote
in message news:pX9HkrSs...@tpsmail01.turbopower.net...
> Hi Greg,
>
> Thanks for the kind words. I've learned more about AsyncPro by
> participating in this newsgroup than any other way.
>
> > I have studied both of your example programs: ExBlock and ExThread. I
think
> > the main difference in my application and yours is that I am using the
> > CommPortTriggerAvail and CommPortTriggerTimer events to trigger the exit
> > from my blocking routine. My blocking routine runs in the same thread
as
> > the ApdComPort was created in (not the main VCL thread though). With
the
> > AdPacket, you can use the SyncEvents parameter to force the events to
fire
> > even though your thread with the AdPort is sleeping (or calling
> > WaitForSingleObject). The CommPortTriggerAvail and CommPortTriggerTimer
> > events won't fire while my thread is sleeping with a sleep(n) or
> > WaitForSingleObject(EventHandle,1000).
>
> Yes, I understand the issues with OnTriggerAvail not having a SyncEvents
> property. However, Mike suggested something to me a while back that I
> haven't tried but should work. The RegisterSyncEventTriggerHandler and
> RegisterEventTriggerHandler methods (in AwUser) already offer both
> alternatives. You should be able to register an event similar to
> OnTriggerAvail.
>
> Are you using the TriggerTimer just for timeout purposes? You should be
> able to do that if you use WaitForSingleObject.
>
> I like this approach since you don't need any sleep or message
> processing for TApdComPort based programs. However, if you use
> TApdWinsockPort in winsock mode then you do need message processing in
> the separate thread as that is not multi-threaded. There is another
> slight problem with winsock in that the main VCL process must have
> message processing happening in order to establish the initial socket
> connection, even if all of your TApdWinsockPort code is in a separate
> thread. That means that the main VCL process can't make a blocking
> function call to establish the socket connection.
>
> Expect to have problems to solve if you use TAPI in such an approach (I
> speak from recent experience).
>
> So, except for winsock and TAPI, it seems to work real well. Enough of
> my hard-earned techniques revealed for one day...
> I used the RegisterEventTriggerHandler method to register a method which I
> use to simply call the SetEvent method to trigger a return from the
> WaitForSingleObject call in my blocking routine. This allows the blocking
> thread to wake up quickly when characters are received. The standard
> TriggerAvail and TriggerTimer events (in the blocking thread) will fire when
> WaitForSingleObject returns and I call SafeYield.
>
> I used a fairly short timeout in the WaitForSingleObject call so that my
> message handling in the thread would still process the TAPI events ok.
> Hopefully the Winsock support will go in easier with this aproach too. With
> these changes, my cpu time is cut down to about 4-5% but the communications
> speed is very fast. I cannot tell any difference in speed from the version
> that used 100% cpu time.
That is very good news. I'm glad to hear it worked for you. I'll have
to try the same thing very soon. Thanks for the feedback!
I used the RegisterEventTriggerHandler method to register a method which I
use to simply call the SetEvent method to trigger a return from the
WaitForSingleObject call in my blocking routine. This allows the blocking
thread to wake up quickly when characters are received. The standard
TriggerAvail and TriggerTimer events (in the blocking thread) will fire when
WaitForSingleObject returns and I call SafeYield.
I used a fairly short timeout in the WaitForSingleObject call so that my
message handling in the thread would still process the TAPI events ok.
Hopefully the Winsock support will go in easier with this aproach too. With
these changes, my cpu time is cut down to about 4-5% but the communications
speed is very fast. I cannot tell any difference in speed from the version
that used 100% cpu time.
Thank you very much for your help.
Greg Dunn
"Gregory A. Dunn" <gr...@eagleresearchcorp.com> wrote in message
news:edIdK7ls...@tpsmail01.turbopower.net...