tcp_mem is more important because it defines how the tcp stack should behave when it comes to memory usage. IMO send and receive buffer should be a multiple of tcp_mem. Here is a link to a formula for receive buffer: http://www.acc.umu.se/~maswan/linux-netperf.txt. In short:
The overhead is: window/2^tcp_adv_win_scale (tcp_adv_win_scale default is 2)
So for linux default parameters for the recieve window (tcp_rmem):
87380 - (87380 / 2^2) = 65536.
Given a transatlantic link (150 ms RTT), the maximum performance ends up at:
65536/0.150 = 436906 bytes/s or about 400 kbyte/s, which is really slow today.
With the increased default size:
(873800 - 873800/2^2)/0.150 = 4369000 bytes/s, or about 4Mbytes/s, which
is resonable for a modern network. And note that this is the default, if
the sender is configured with a larger window size it will happily scale
up to 10 times this (8738000*0.75/0.150 = ~40Mbytes/s), pretty good for
a modern network.
Here is what the article says about tcp_mem:
What you remove is an artificial limit to tcp performance, without that limit
you are bounded by the available end-to-end bandwidth and loss. So you might
end up saturating your uplink more effectively, but tcp is good at handling
this.
IMO a bigger middle tcp_mem value speeds up connection at the loss of less security and slightly increase memory usuage.
You can monitor the network stack with:
grep skbuff /proc/slabinfo