I second the general idea of Dmitry Grigoryev’s answer: your best option
is to measure a round-trip time and use half of that as an estimate of
the one-way time. Otherwise you will have too many unknowns. For
example, you don't know how long your OS takes to process the outgoing
message and send it through USB to the USB/serial bridge inside the
Arduino. As an optimization, I would send the time information and the
synchronization strobe as two separate messages, with the latter being a
single byte. This way the latency of the synchronization strobe (the
only latency that matters) is minimized.
Latency of serial communication
I did some research to try to nail this one down. At 57600 bits/s,
the theoretical time per bit is about 17.4 µs, as stated in the
Wikipedia article you linked to. In practice, the actual time can be
rounded more or less depending on the UART capabilities and the clock
speed. You did not specify what Arduino you are using. In the following,
I will assume an AVR-based Arduino clocked at 16 MHz, which is
presumably the most common.
The UART in the AVR constrains the bit time to be a multiple of
8 CPU cycles, i.e. 0.5 µs when running at 16 MHz. The
closest you can get to the ideal timing is therefore 17.5 µs.
However, the Arduino core library has a hard coded compatibility
exception which, in this very specific case, sets the bit
duration to 17 µs instead. Since you are presumably configuring the
port at /8N1, which is the default, the time per byte is then
170 µs (1 start bit, 8 data bits and 1 stop bit).
Actually, when transmitting a single byte, the transmission time is
slightly less than that. The UART can report the byte as received as
soon as it is done taking the required three samples of the stop bit,
which happens slightly after the middle of that stop bit. The
theoretical time it takes to transmit a single byte is then about
9.56 times the single-bit duration, or about 162.56 µs at
57600/8N1.
I did a simple loopback test with the TX and the RX of my Uno shorted
together. I used a timer to time the execution of the following code:
Serial.write('.');
while (!Serial.available()) continue;
The result was 182.38 µs, or about 10.73 bit durations. A
fraction of this time is taken by the execution of Serial.write()
and
Serial.available()
. In order to get closer to a bare hardware latency,
I also timed a low-level version of the two lines above:
UDR0 = '.';
while (!bit_is_set(UCSR0A, RXC0)) continue;
This has to be run with interrupts disabled. The execution time was now
between 164.19 and 164.81 µs, i.e. 9.66 to 9.69 bits
durations.
Alternative approach
As a final note, I would recommend you consider buying a GPS module with
a 1PPS output. This 1PPS is a 1 Hz logic signal with the rising
edges tightly aligned to the start of the UTC seconds. You typically get
an accuracy in the tens of nanoseconds. Since this is just a logic
signal that you can easily compare with the 1 Hz output of your RTC
module, you get rid of all the latency issues that come with computers
(your NTP client), or data links (USB, serial, I2C).