Socket + Bind on server side

Hi, I have been trying to optimize some code. I came across a thought as below - I wonder why Socket and Bind are separate in the case of Server ? Why can't the Socket call create the address directly for the newly created socket instead of doing it via a Bind call ? Any ideas ?

I think that this will be a good optimization point to consider as it could save some instruction cycles .

Thx in advans, Karthik Balaguru

Reply to
Karthik Balaguru
Loading thread data ...

Did you profile it before?

Because there are not just server socket. A socket may be used in many different ways. Packing it all into one single call is a very bad idea.

Optimization happens on the protocol/implementation level, not the instruction level. You start there, you're on the wrong track.

Again: Did you profile the program? Is it in fact CPU bound? Did you compare the huge workload performed by both socket(...) and bind(...) to the little work that is done inbetween? And even if socket(...) and bind(...) were merged the overall workload would about the same.

Wolfgang

Reply to
Wolfgang Draxinger

What if you want to do something to the socket before you bind it? What if you don't want to bind it? What if 'socket' needs to return an error code? What if you need to obtain information about the socket before you know how to bind it?

Where would the savings come from exactly?

DS

Reply to
David Schwartz

In which context ? Normally it is creation of a socket, get the descriptor and associate the socket with a port & a address.

Here, on the server side, we might be going in for both socket & bind calls. Hence they can be merged. But, there are scenarios on the client side that might not require a bind. I too had the same thought and hence only making it specific to the server side.

It can be handled. This can be at the end of the combination of socket & bind. It can specify socket specific error codes and bind specific error codes.

Are you conveying about the AF_INET and AF_LOCAL related typecasting differences ? Normally, bind is about associating the socket id with an address and port number.

Every call to a function will consume some instructions on any processor. So, normally few related functions can be merged. I think, the same can be thought of here w.r.t server side alone.

It is not a very big saving, but just few savings.

Thx in advans, Karthik Balaguru

Reply to
Karthik Balaguru

Right, but what if you want to do something *before* you bind it? For example, you may want to setup port reuse. You may want to change default buffer sizes.

But then there is no savings. If you still need a separate 'socket' call and a 'bind' call, what can the combined call do other than call 'socket' and then call 'bind', which is what you already do. So all it would do is add an *extra* call. Now, you call 'socket', then you call 'bind'. With the suggested change, you'd call some function that would first call 'socket' and then call 'bind'. So two calls would go up to three.

So now there's an extra test between socket and bind. So now the cost is getting higher.

Old system: Call socket, check for error, call bind, check for error.

New system: Call new call. It calls socket, checks for error, calls bind, returns. We have to check if the error is a socket error or a bind error.

Wow, what a savings!

But since you still need a separate 'socket' and 'bind', all you've done is add a layer of indirection. You haven't suggested any reason to think the combination will save anything.

It's no savings, since you have the added overhead of a new combined function which still calls the two internal functions. If you want to argue that there would be a savings, you actually have to do that. For example, you can argue that the 'bind' call could already know the internal socket structure rather than having to look it up in the process' socket table. But just combining two functions into one doesn't reduce overhead, it increases it by adding an extra function call.

DS

Reply to
David Schwartz

What matters is the work actually done. Even if you combined socket(...) and bind(...) into a single call, all the tasks of both socket and bind still would need to be done. Now just take a look how many subcalls both socket(...) and bind(...) do: It's in the order of some hundreds. Compared to this these little two separate calls contribute almost nothing.

You're talking about micro optimization here, some technique that seldomly gains you something. socket(...) ... bind(...) are both CPU bound, but server applications normally suffer on the I/O side, so if I were to optimize something, I'd start there.

Wolfgang

Reply to
Wolfgang Draxinger

New system : Call new call(replacement for socket call, let it be termed as 'sockbind'.Here it will create the socket and will also do bind), Check error.

By having error specific return values, can avoid the checking to determine if it is a socket error or bind error.

It can be as below -

1.Unix domain socket(few characters ) - sockbind (int domain, int type, int protocol, (struct sockaddr *) &addr, length)

2.Unix domain socket(more characters) - sockbind (int domain, int type, int protocol, (struct sockaddr_un *) &addr, length)

3.Internet domain socket - sockbind (int domain, int type, int protocol, (struct sockaddr_in *) &addr, length)

That new call might be useful only on server side.

Yes, It appears to be just combining two functions, but i think there are other things to consider that improves it a bit. Even the number of arguments to the new call can be minimized by clubbing many elements and using structures to pass by reference. So, the number of calls and the arguments being passed gets reduced.

But, yes the amount of benefit is less !!

Karthik Balaguru.

Reply to
Karthik Balaguru

and

Yes, but there can be some saving in the function calls and the arguments being passed that inturn could result in little bit of improvement. Yes, the benefit is less.

d

:-) :-)

y

Interesting point of view, as the earlier is micro optimization that provides less gain.

Karthik Balaguru

Reply to
Karthik Balaguru

How will that reduce the number of arguments passed? The new combined function will still have to call some equivalent of 'socket' and pass it the same parameters and then call some equivalent of 'bind' and pass it the same parameters. The only difference will be that a new function will be added to the call path.

I still don't see where any benefit or savings would come from.

Again, as I said, to argue there's some kind of savings you'd have to point out some benefit from combining the functions. For example, there might be some savings if socket is internally implemented like this:

1) Allocate internal socket. 2) Lock process socket table. 3) Assign process socket handle. 4) Unlock process socket table. 5) Return handle.

And bind is implemented like this:

1) Lock process socket table. 2) Look up handle in table. 3) Unlock process socket table. 4) Call internal bind function. 5) Return results.

Then your internal function could avoid some steps if implemented like this:

1) Allocate internal socket. 2) Call internal bind function. 3) Lock process socket table. 4) Assign process socket handle. 5) Unlock process socket table. 6) Return results.

See how here there is an actual savings? "It saves a call by adding a call" (since it has to call socket and bind internal functions) is not a savings. Only "it avoids some work that would otherwise be done twice" is a savings.

But, on the flip side, you have some added complexity with this. If step 4 fails, you have already bound when you should not have. Some protocols do not make it possible to instantaneously tear down a binding and you may have to clean up pending connections.

So my bet is that these optimizations wouldn't actually work out in practice and the added overhead of handling different error cases and releases the socket on bind failure would make it totally not worth it.

DS

Reply to
David Schwartz

See setsockopt(2)

For instance, you may want to set the receive buffer in a TCP to a larger value. This is important on long fat networks, such as when the ping time is > 500 milliseconds, as in satellite connections.

Or you may want to set the broadcast flag for UDP sockets.

Reply to
Maxwell Lol

Well, considering that you have to handle every possible combination of UNIX domain sockets, TCP sockets, UDP sockets, DCCP, Appletalk, multicast, broadcast, etc. And there is the linger, keepalive, send and receive buffer, and reuse options.

And the differences between a client and a server socket.

If you had ONE call, the parsing of all of the different combinations possible would be significant, and expensive because it's done in the kernel instead of the user mode. Plus the error handling would also be made much more complicated. This also complicated the user code that has to handle the error and try to resolve how to report/fix it.

If you want, write a library or a macro to make it easier to code, go ahead.

Reply to
Maxwell Lol

Okay.

Karthik Balaguru

Reply to
Karthik Balaguru

Interestingly, yes, i do find that setsockopt() manipulates the options associated with a socket. I think, this point seems to be very important as the options affect the socket operations such as the routing of packets, out-of-band data (data marked Urgent), lingering of socket if data is present, Send/Receive buffer size, Keepalive(if supported by protocol) features. Thx for the tip !

Karthik Balaguru

Reply to
Karthik Balaguru

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.