From: Hector Santos on
Joseph M. Newcomer wrote:

>> No, a recv() is a loop and you read 8K at a time:
> ****
> Note that you read AT MOST 8K, and that's because of the sizeof(buf) parameter to the recv
> being 8*1024. If you made it 16*1024, you might receive up to 16K at a time, but in all
> cases, this is the MAXIMUM that will be returned; you might get fewer bytes, based on
> network traffic and your sender and receiver stacks.


Joe, the reason 8K is used is because by default the winsock stack
packet size is set to 8K.

So in practice, it is better to keep it aligned with the what the
socket has otherwise you can run into pressure points and bucket
brigade situations.

You can get/set change socket send/recv sizes as show with the example
below. 8K is the default. But in principle, not only is stack is set
to a certain size, the stacks at nodes in between END POINTS are set
as well too. You need to look for bucket brigade scenarios where you
sending 32K packet sizes, but the receiver is still at 8K, that means
it has I/O Pending at least 4 times.

Overall, in communications whether for RS232, sockets, etc, the rule
of thumb for data transfer efficiency is:

- SEND LOW
- RECEIVE HIGH

The sender does not know what a receiver can handle, so you don't want
to over pressure it. However, a receiver knows what it can handle so
it should be ready to receive as much it can. If your communication
products deviates from this, you will see inefficient data transfer
scenarios.

// File: testwinsock1.cpp
// compile: cl testwinsock1.cpp

#include <windows.h>
#include <stdio.h>
#include <winsock.h>
#include <conio.h>

#pragma comment(lib,"wsock32.lib")


int main(char argc, char *argv[])
{
WSADATA wd;
int size;
int n;

if (WSAStartup(MAKEWORD(1, 1), &wd) != 0) {
return 1;
}

SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);

n = sizeof(int);
getsockopt(sock, SOL_SOCKET,SO_SNDBUF,(char *)&size,&n);
printf("SO_SNDBUF: %d\n",size);

n = sizeof(int);
getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&size,&n);
printf("SO_RCVBUF: %d\n",size);

closesocket(sock);
return 0;
}

Output:

SO_SNDBUF: 8192
SO_RCVBUF: 8192


--
HLS
From: Hector Santos on
Joseph M. Newcomer wrote:

>>>>> Its very simple with the server model:
>>>>>
>>>>> s = socket() - create a socket handle
>>>>> bind(s) - associate an local IP with socket
>>>>> s handle
>>>>> listen(s) - starting to listen to connection
>>>>> accept(s,c) - wait for clients, new socket c
>>>>> for connect
>>>>>
>>>>> CHECK PEER IP ADDRESS OF C IN FILTER LIST,
>>>>> IF FOUND, CLOSE SOCKET GOTO BACK TO ACCEPT
>>>>>
>>>>> recv(c) - receiver whatever
>>>>> send(c) - send whatever
>>>>> shutdown(c) - tell remote I'm about to close
>>>>> closesocket(c) - close socket handle
>>>>> go back to accept


>>> HLS
>> That is great Hector. It looks like the basic architectural
>> design is set. I won't limit myself to mongoose in the long
>> run.
> ****
> Note that what is illustrated here is what is called an "iterative servier", that is,
> while it is processing one transactiion, it cannot accept other connections, because it
> needs to go back to the Accept statement. There is also a concept called a "concurrent
> server" where you hand the accepted socket over to a separate thread and immediately
> return to the Accept statement.


Correct. The above simple pseudo code illustrated a layman example
for Pete's sake. <g> It was taken without saying it could be spawn
off into a thread, but I didn't want to complicate the pseudo code:

VOID LISTEN_THREAD()
BEGIN
s = socket() - create a socket handle
bind(s) - associate an local IP with socket s handle
listen(s) - starting to listen to connection
accept(s,c) - wait for clients, new socket c for connect
CREATE_THREAD( SPAWN_THREAD, &c)
go back to accept
END

VOID SPAWN_THREAD(c)
BEGIN
CHECK PEER IP ADDRESS OF C IN FILTER LIST,
IF FOUND, CLOSE SOCKET GOTO BACK TO ACCEPT

recv(c) - receiver whatever
send(c) - send whatever
shutdown(c) - tell remote I'm about to close
closesocket(c) - close socket handle
END

--
HLS
From: Joseph M. Newcomer on
See below...
On Sat, 20 Mar 2010 10:18:43 -0500, "Peter Olcott" <NoSpam(a)OCR4Screen.com> wrote:

>
>"Hector Santos" <sant9442(a)nospam.gmail.com> wrote in message
>news:%23gh1e5DyKHA.5292(a)TK2MSFTNGP06.phx.gbl...
>> Peter Olcott wrote:
>>
>>> Oh now I see where you are getting the 3.7 minutes from.
>>> The actual maximum time per user request is 1/10 second
>>> for a whole page of data. Requests larger than a page of
>>> data will be placed into a lower priority queue. The
>>> system recognizes 72,000 characters per second. My OCR
>>> does not need to change much, it just needs to get its
>>> requests from a FIFO queue. The webserver will have
>>> multiple threads to append to this queue.
>>>
>>>> You need to focus first on making sure you can scale the
>>>> OCR application. Making it thread ready and safe is a
>>>> first step.
>>>
>>> It does not need to be thread ready, it only needs to be
>>> able to read from a FIFO queue.
>>
>> Ok, I'll try this again (I already posted the points here
>> but the mail was freaking lost), try it again in simple
>> terms:
>>
>> THINK TRANSACTION TIME!
>>
>> How what are your boundary conditions for a HTTP request
>> transaction time, both minimum and maximum?
>>
>> Based on what you said below:
>>
>> minimum: 100 ms per PAGE OF META DATA
>> maximum: DELAYED PROCESSING
>>
>> Look, you are touching base with all sorts of common
>> practice engineering design principles in this area. How
>> about this so you can cut down on mail-tagging thread?
>>
>> What is your functional specification, NOT TECHNICAL,
>> functional
>> specification of the OCR application?
>>
>> In short, you either have:
>>
>> - fast *semi-interactive* client/server framework
>> - delayed store and forward client/server framework
>>
>> This changes (or rather defines) all sorts of things.
>> This all goes back to my original input:
>>
>> You need to work out the OCR state machine protocol.
>>
>> From there, you can put together the solution you need. I
>> had a basic idea of what you needed from the beginning,
>> that is why I guided you to the CSPServer class at
>> codeproject.com
>>
>> But even then, you still need to make it all thread ready
>> and safe, regarding its interactive or store and forward,
>> or fifo, lifo, or what have you.
>>
>> In other words, but you can even begin to talk having a
>> party, you need to get the house ready for many guest.
>>
>> --
>> HLS
>
>I did not fully understand much of the above.
>
>My OCR process has the following requirements:
>(1) Must be a single thread on a machine dedicated to OCR
>processing.
****
That's where Hecor & I are questioning the basic assumption of single-threadedeness. He
says that mongoose requires a multithread-capable algorithm, Since your DFA is static
once loaded, it requires no locking to access it. So why is your code not
multithread-readly already?
****
>(2) Its data must remain resident in RAM
****
Only vaguely under your control. The OS handles this.
****
>(3) Its input will be a less than 100K 24-bit color PNG file
>coming over HTTP.
****
But it could be larger, a whole page. Or do you plan to reject larger requests with a
message
<html>
<body>
You requestion of (value here)K is larger than we accept for this service. Please limit
your request to files of (valud here)K or smaller.
</body>
</html>
****
>(4) Its output will be less than 10K of UTF-8 text.
***
Not even relevant. It will probably be < 1K most times.
****
>(5) OCR processing time is less than 100 milliseconds.
****
As you point out, if there are 10 requests pending, this mens 1sec, which violates your
500ms goal. But if you had a concurrent server, it would be (nrequests * 100)/ncores
milliseconds, so for a quad-core server with 10 pending requests and a 4-thread pool you
would have only 250ms, within your goals. If response time is so critical, why are you
not running multithreaded already?
****
>
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Hector Santos on
Peter Olcott wrote:

> I am thinking that the web server part will spawn a thread
> for each request, and append this request at the end of a
> FIFO queue, then this thread dies. My OCR process would read
> requests from the head of the queue, and process them one at
> a time in a single thread.

Terrible!

I would like to hear what the client will be doing waiting a response
where each one will have a linear incremental delay factor as the
queue builds.

--
HLS
From: Peter Olcott on

"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in
message news:899aq5lum2a0h89btkvfgvekpoqu68og19(a)4ax.com...
> See below...
> On Sat, 20 Mar 2010 10:18:43 -0500, "Peter Olcott"
> <NoSpam(a)OCR4Screen.com> wrote:
>
>>
>>"Hector Santos" <sant9442(a)nospam.gmail.com> wrote in
>>message
>>news:%23gh1e5DyKHA.5292(a)TK2MSFTNGP06.phx.gbl...
>>> Peter Olcott wrote:
>>>
>>>> Oh now I see where you are getting the 3.7 minutes
>>>> from.
>>>> The actual maximum time per user request is 1/10 second
>>>> for a whole page of data. Requests larger than a page
>>>> of
>>>> data will be placed into a lower priority queue. The
>>>> system recognizes 72,000 characters per second. My OCR
>>>> does not need to change much, it just needs to get its
>>>> requests from a FIFO queue. The webserver will have
>>>> multiple threads to append to this queue.
>>>>
>>>>> You need to focus first on making sure you can scale
>>>>> the
>>>>> OCR application. Making it thread ready and safe is a
>>>>> first step.
>>>>
>>>> It does not need to be thread ready, it only needs to
>>>> be
>>>> able to read from a FIFO queue.
>>>
>>> Ok, I'll try this again (I already posted the points
>>> here
>>> but the mail was freaking lost), try it again in simple
>>> terms:
>>>
>>> THINK TRANSACTION TIME!
>>>
>>> How what are your boundary conditions for a HTTP request
>>> transaction time, both minimum and maximum?
>>>
>>> Based on what you said below:
>>>
>>> minimum: 100 ms per PAGE OF META DATA
>>> maximum: DELAYED PROCESSING
>>>
>>> Look, you are touching base with all sorts of common
>>> practice engineering design principles in this area. How
>>> about this so you can cut down on mail-tagging thread?
>>>
>>> What is your functional specification, NOT TECHNICAL,
>>> functional
>>> specification of the OCR application?
>>>
>>> In short, you either have:
>>>
>>> - fast *semi-interactive* client/server framework
>>> - delayed store and forward client/server framework
>>>
>>> This changes (or rather defines) all sorts of things.
>>> This all goes back to my original input:
>>>
>>> You need to work out the OCR state machine protocol.
>>>
>>> From there, you can put together the solution you need.
>>> I
>>> had a basic idea of what you needed from the beginning,
>>> that is why I guided you to the CSPServer class at
>>> codeproject.com
>>>
>>> But even then, you still need to make it all thread
>>> ready
>>> and safe, regarding its interactive or store and
>>> forward,
>>> or fifo, lifo, or what have you.
>>>
>>> In other words, but you can even begin to talk having a
>>> party, you need to get the house ready for many guest.
>>>
>>> --
>>> HLS
>>
>>I did not fully understand much of the above.
>>
>>My OCR process has the following requirements:
>>(1) Must be a single thread on a machine dedicated to OCR
>>processing.
> ****
> That's where Hecor & I are questioning the basic
> assumption of single-threadedeness. He
> says that mongoose requires a multithread-capable
> algorithm, Since your DFA is static
> once loaded, it requires no locking to access it. So why
> is your code not
> multithread-readly already?

Mongoose will use its multiple threads to append to the end
of a single FIFO queue, The OCR will read from the head of
this queue.

> ****
>>(2) Its data must remain resident in RAM
> ****
> Only vaguely under your control. The OS handles this.
> ****
>>(3) Its input will be a less than 100K 24-bit color PNG
>>file
>>coming over HTTP.
> ****
> But it could be larger, a whole page. Or do you plan to
> reject larger requests with a
> message

They get placed in a lower priority queues, and are charged
a higher price.

> <html>
> <body>
> You requestion of (value here)K is larger than we accept
> for this service. Please limit
> your request to files of (valud here)K or smaller.
> </body>
> </html>
> ****
>>(4) Its output will be less than 10K of UTF-8 text.
> ***
> Not even relevant. It will probably be < 1K most times.
> ****
>>(5) OCR processing time is less than 100 milliseconds.
> ****
> As you point out, if there are 10 requests pending, this
> mens 1sec, which violates your
> 500ms goal. But if you had a concurrent server, it would
> be (nrequests * 100)/ncores
> milliseconds, so for a quad-core server with 10 pending
> requests and a 4-thread pool you
> would have only 250ms, within your goals. If response
> time is so critical, why are you
> not running multithreaded already?
> ****

If I get more than an average of one request per second, I
will get another server. My process does not improve with
my multiple cores, it does get faster with faster memory.
800% faster memory at the same core speed provided an 800%
increase in speed. Two processes on a quad core resulted in
half the speed for each.

>>
>>
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm