Subject: Re: Efficiency of caller/toss

From: John Goerzen <[email-masked]>
Date: Wed, 18 Aug 2021 14:20:09 -0500

Hi Sergey, and thanks for all the helpful info as usual!

On Wed, Aug 18 2021, Sergey Matveev wrote:

> *** John Goerzen [2021-08-18 08:56]:
>>So while looking into the question of "how could I have the 
>>quickest
>>delivery and execution of packets between machines on a LAN"
>
> I am sure that if we are dealing with <=1Gbps Ethernet, then the 
> main
> bottleneck is the network itself and TCP-related algorithms. If 
> we deal
> with >=10Gbps links and especially high-latency ones, then TCP 
> is the
> thing you are likely have to tune. That is why I played with 
> various

So in this particular case, I have fairly small TCP packets going 
over a LAN.  The transport and TCP speeds aren't really concerns; 
it more the latency of waiting for the next toss cycle that gets 
me.  I want things to be tossed ASAP, but there's a fine line 
between that and having pathological things occur when error 
packets are present.

> that, but with an ordinary 1Gbps Ethernet adapter and 
> short-length home
> network all of that is behind an ordinary TCP. Possibly fine TCP 
> tuning
> will be always enough for NNCP.
> https://en.wikipedia.org/wiki/TCP_congestion_avoidance_algorithm

I've been happy enough with it.  Yes, TCP does have its 
pathologies, especially on high-latency WAN links, but for an 
asynchronous tool, it probably doesn't merit further work right 
now.

> Then comes CPU and memory. I assume that battery life depends 
> mainly on
> CPU. Cryptographic algorithms used in NNCP are some kind of the 
> fastest
> ones: ChaCha20-Poly1305 and BLAKE3. AES-GCM with hardware 
> acceleration
> could be faster (and less CPU hungry), but that will complicate
> SP-protocol with algorithm negotiation, that I won't do. But 
> neither
> ChaCha20-Poly1305, nor BLAKE3 implementations use multiple CPUs 
> now.
> Multiple connections will be parallelized, because they will 
> work in
> multiple independent goroutines.

Right.  In my particular case here, the packets are small and so 
the CPU usage of actually processing them is on the order of a few 
ms per hour, I'm assuming.  I'm more thinking of background CPU 
usage here.

Of course, my backup setup processes 250GB packets on occasion, so 
the calculation is very much different there!

> and only after that begin its processing, with another fsyncs.
> Performance and reliability guarantees are opposites. Turning 
> off fsync
> (zfs set sync=disabled, mount -o nosync), atime, .hdr files of 
> course
> will hasten NNCP.

Yep.  Also here, in this particular use case, I'm more concerned 
about background usage than foreground usage.

> Constant rereading of spool directory, stat-ing files in it, 
> locking --
> generally won't create any real I/O operations to the disk, 
> because of
> filesystem caching. And of course it won't wearout SSDs, because 
> it is
> read operations. But it consumes CPU, indeed.

I would assume that the creation and deletion of the lock file 
would add things to logs on various filesystems, which must be 
committed, but I could be wrong about that.  Still, even if it's 
doing it every second as with autotoss, probably negligible 
compared to what a web browser does when you make one click.

> Instead of constant rereading of directory contents, software 
> can use
> various frameworks like kqueue and inotify, that will explicitly
> immediately notify about changes, without the need of an endless
> expensive loop with a sleep. But all of that is OS-specific, 
> that is why
> I am not looking in that direction. I am not against that kind 
> of

Right.  That is a real pain to deal with.

> handshake packets padded to their maximal size of ~64KB. So 
> handshake
> should be very expensive (traffic, delays, CPU) comparing to 
> long-lived
> sessions.

Makes good sense, thanks.

>>Is there a way, since autotoss is in-process with nncp-caller, 
>>to only
>>trigger the toss algorithm when a new packet has been received, 
>>rather than
>>by cycle interval?
>
> Can be done. Should be done :-). Current autotosser runs 
> literally the
> same toss-functions as nncp-toss.

This strikes me as perhaps the single best cost-benefit thing 
we've discussed here.  If it could just change how the toss is 
invoked, from being timer-based to trigger-based, that should be 
pretty nice.  One complication I could forsee would being needing 
to remember to trigger it again if new packets come in while a 
toss is already running, but that's not particularly difficult to 
overcome.

> I remember about that issue and about the whole problem of 
> (unexistent)
> errors processing. Currently I just had no time to think about 
> that. And
> in the nearest weeks won't start thinking about it too... 
> various other
> things in real life I have to finish :-)

Completely understood!  I am most definitely NOT complaining, just 
thinking!

>>2) Called are made only when cron says to, but only if an 
>>outgoing packet
>>exists.  (when-tx-exists causes FEWER calls than cron alone)
>>I'm guessing it's #2 but I'm not certain.
>
> Yes, exactly like you wrote here. when-tx-exists just tells, 
> every time
> we appear to make a call, to check if there really exists any 
> outgoing
> packet (with specified niceness).

It might be useful to add that exact sentence (or mine) to the 
documentation, incidentally.

- John