The Ethernet device at any time can send a status string noting any
event it has encountered so with this single thread implementation I'm
using select() to determine the status of recv() before actually
calling it. Three different timeouts are used:
* 0 ms - flush recv() for any status strings
* 150 ms - wait for ACK/NAK from Ethernet device, also parse for
status string
* 1 ms - check for any data, parse for status string. Used for a
timeout looping function. (User enters a command and a timeout value
in milliseconds. The Ethernet device executes the command and returns
a status string when finished.)
I've been running timing tests and when select() is used with a
timeout of 1 ms ( 1000 in the tv_usec element in the timeval
structure) it takes more than 1 ms to timeout. Averages between 7 -
10 ms. I know that timing on the PC is not exact (online searches and
books place it around 25 - 75 ms) but is there some way to make the
resolution to 1 ms?
Thank you,
Jonnyair
using:
* XP sp2
* Visual Studio 6 sp6
* WinSock ver. 2.2
> [...]
> I've been running timing tests and when select() is used with a
> timeout of 1 ms ( 1000 in the tv_usec element in the timeval
> structure) it takes more than 1 ms to timeout. Averages between 7 -
> 10 ms. I know that timing on the PC is not exact (online searches and
> books place it around 25 - 75 ms) but is there some way to make the
> resolution to 1 ms?
Not as far as I know. The default clock interval on Windows is, if I
recall correctly, 15ms. So you won't get better resolution than that with
things that use that clock for timing. I believe this includes select().
That said, 1 ms is miniscule compared to the potential latency in Ethernet
and the associated drivers and whatnot. IMHO, it's not practical to have
a design that relies on such a short timeout when dealing with networking
code.
Also, while I doubt that "signaled events" and "critical sections" are
really as big a performance problem as you seem to think they are,
depending on what exactly your code is you could use IOCP for your
networking code without having to implement inter-thread communication.
The easiest way, of course, would be to just make sure you can do whatever
processing you need from within the completion thread.
I've never heard of anyone who cared about performance choosing a design
that uses select(), never mind a design that uses select() and puts all of
the processing into a single thread. I suspect that has more to do with
the appropriateness (or lack thereof) of such a design for
high-performance applications, than it does with me just missing someone
mentioning it.
Pete
Thanks Pete for your input. My initial goal is to supply an API that
allows sending of data to the Network device then sit and wait for a
user defined timeout. If timeout, return with error. If response
before timeout, return with SUCCESS.
I'm being pushed to make this timeout resolution as tight as possible
but I am dealing with the "Ethernet" beast and the powers that be
really don't understand that.
As to the threaded option, I would rather use it instead of the single
threaded linear design but the way it works now is to slow. I could
be implementing it wrong so any input would be greatly appreciated. I
know it's outside of the scope of this newsgroup but if interested
below is a short description:
Once the socket is created and a connection is made to the Network
device a thread is created (using CreateThread() API) passing all
pointers to events and the socket. It sits and spins in a loop,
blocking on recv(). Any data received gets processed, parsed for
data, ACK/NAK or status flag, variables wrapped in Critical Sections
are updated (only if data is received) then appropriate Event is set
(if status flag then set status flag Event).
The user calls a function that sends the data (send()) to the
controller then it waits for a predetermined time period using
WaitForSingleObject() to receive an ACK or NAK (depending on the
network device's state) data packet back. Using Ethereal I can see
that the whole turn around time from sending the data to receiving the
ACK/NAK back is ~5ms. But for some reason, there is a big lag once
the recv() thread gets the ACK/NAK and triggers the ACK/NAK Event
(SetEvent()) to signal the main process that the correct data pack was
received. Removing the parser has no effect no effect.
Jonny
> [...] Using Ethereal I can see
> that the whole turn around time from sending the data to receiving the
> ACK/NAK back is ~5ms. But for some reason, there is a big lag once
> the recv() thread gets the ACK/NAK and triggers the ACK/NAK Event
> (SetEvent()) to signal the main process that the correct data pack was
> received. Removing the parser has no effect no effect.
Define "big lag". You cannot expect precise answers unless you provide
questions with precise information.
Fundamentally, Windows is not a real-time OS. None of the operating
systems most people are familiar with are. If you are seeing delays of
500 ms or more, then there's something wrong. If you're seeing delays of
say 10-30ms or so, then that's normal thread scheduling going on and
there's nothing you will be able to do about. However: because it's
thread _scheduling_ and not the cost of the context switch that is causing
the issue, putting everything into a single thread isn't going to change
much.
Doing that will affect the timing a little, but you are still at the mercy
of the thread scheduler; your recv() function call isn't going to complete
the moment that data comes in. It will complete (that is, return to the
caller) the next time the thread gets scheduled to run, which could be
quite a bit later (dozens of ms or more, depending on what else is going
on in the computer) than when the data is received.
Anyway, I'm not a Windows thread scheduling expert, so the above is
nearing the limit of the information I'd be able to provide. However, I
can tell you that your question has a lot less to do with Winsock than it
has to do with Windows thread scheduling. As such, you'd likely get
better, more useful information posting to a newsgroup specific to those
issues, than to this Winsock programming newsgroup (especially given how
inactive this newsgroup has been lately...for all I know, I'm the only one
in the world left reading it :) ).
Pete