Recent

Author Topic: Serial seems to be slow  (Read 2631 times)

kensmith

  • New Member
  • *
  • Posts: 15
Serial seems to be slow
« on: June 07, 2022, 08:09:19 pm »

I suspect that the serial unit spins up a thread to watch the serial port.  For what I am doing with the serial port, this is not a great thing.
Basically I want to:
1) put one character into the output buffer of the UART
2) detect if an received character is waiting in the input buffer.
3) Get that character.
All of my code works one byte at a time and has to do logic on every received byte.
Right now something that should take about 10 Minutes at 115200 baud takes about 1.5 hours.  The code never even gets close to shoulder characters as it works.
Nobody is going to mind if my program makes the computer unresponsive for several seconds at a time.  I am already running the Application.ProcessMessages at a few points in the code to let user actions slip by while I have a gap in what I need to do.
Would TLaxSerial be better or is there some other option to get the speed up?

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: Serial seems to be slow
« Reply #1 on: June 08, 2022, 09:42:53 am »
Hello,
can you show  us  the code ?
Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Serial seems to be slow
« Reply #2 on: June 08, 2022, 09:48:43 am »
I suspect that the serial unit spins up a thread to watch the serial port.

/WHICH/ serial unit? serial.pp most definitely does not.

What's your target OS? What version of compiler etc.? Have you got an example that demonstrates the problem?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Serial seems to be slow
« Reply #3 on: June 08, 2022, 02:49:47 pm »
Would TLaxSerial be better or is there some other option to get the speed up?
Before concluding that you have a software issue, more information is required (as mentioned by J.P. and Mark).  Also, the hardware interface may be important.  It is likely that you are using some kind of USB-serial converter, in which case the data transfer is subject to USB polling delay.  Then the OS driver may use buffering with a small delay to try and pack as much data into a USB packet as possible.  This may be bad for the latency of short data bursts.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Serial seems to be slow
« Reply #4 on: June 08, 2022, 04:54:44 pm »
Hi!

What you are trying to do is called the Kermit Protocoll.
It was widely used in the late 70s and early 80s on then unstable serial lines.

There were a lot of implementations in C, Turbo Pascal, Basic ,  ...
You should find the Turbo sources in the Net.

If you set the fpc in the Turbo Mode then the Port Array is supported (Only Linux and DOS).

With a port assignement you can directly fetch or send bytes from the UART.
That's how we used the serial lines at that time with CP/M or DOS.

I don't know if that works with todays Hardware and OS but you could give it a try.

Winni

PS.: The Kermit sources for nearly everything including Turbo Pascal:

http://www.columbia.edu/kermit/archive.html

« Last Edit: June 08, 2022, 05:10:22 pm by winni »

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: Serial seems to be slow
« Reply #5 on: June 08, 2022, 06:06:02 pm »

I suspect that the serial unit spins up a thread to watch the serial port.  For what I am doing with the serial port, this is not a great thing.
Basically I want to:
1) put one character into the output buffer of the UART
2) detect if an received character is waiting in the input buffer.
3) Get that character.
All of my code works one byte at a time and has to do logic on every received byte.
*snip*

Using serial one byte at a time is an overkill. If you do that in a tight loop then most of time was spent into the OS primitives (for checking) and then everything freezes. Especially with USB-to-com, as ccrause noted, it takes time x10. You may check less often, but then the transfer rate will drop even more,

Edit: Sorry but pressed Post incidentally...

The only way to implement efficiently such a byte-by-byte protocol is with a dedicated communication processor, i.e. micro-controller.
You must show your code or some more info to decide is there something that can be done about that byte-by-byte approach.
« Last Edit: June 08, 2022, 06:12:41 pm by y.ivanov »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

kensmith

  • New Member
  • *
  • Posts: 15
Re: Serial seems to be slow
« Reply #6 on: June 09, 2022, 12:59:17 am »
Hello,
can you show  us  the code ?
Friendly, J.P

I'd rather not show the whole code.  Partly because there is a huge amount of code but here is a simple bit of code:

Code: [Select]
procedure TSerialCable.SendByte(Data : byte);
begin
  BugEnter(3);
  FakeMultitask;
  SerDrain(Handle);
  BugLeave(3);
  BugEnter(4);
  SerWrite(Handle, Data, 1);
  BugLeave(4);
  end;
BugEnter and BugLeave are just part of my debugging code.
FakeMultitask calls Application.ProcessMessages one out every 10 calls.
Code: [Select]
function TSerialCable.MustGetByte(TimeOut : longint) : byte;
begin
  Result := 0;
  TimeOut := TimeOut * 10;
  while SerRead(Handle,Result,1) < 1 do begin
    SerDrain(Handle);
    FakeMultitask;
    NonBlockingDelay(100);
    dec(TimeOut);
    if TimeOut < 1 then begin
      Result := 0;
      DisplayJamError(jecNotResponding,'nothing received',0);
      exit;
      end;
    end;
  end;
NonBlockingDelay works in microseconds.  It does a Application.ProcessMessages until it is close to the requested time.

kensmith

  • New Member
  • *
  • Posts: 15
Re: Serial seems to be slow
« Reply #7 on: June 09, 2022, 01:01:56 am »
Would TLaxSerial be better or is there some other option to get the speed up?
Before concluding that you have a software issue, more information is required (as mentioned by J.P. and Mark).  Also, the hardware interface may be important.  It is likely that you are using some kind of USB-serial converter, in which case the data transfer is subject to USB polling delay.  Then the OS driver may use buffering with a small delay to try and pack as much data into a USB packet as possible.  This may be bad for the latency of short data bursts.
This may indeed be the problem.  I am using a USB-RS232 converter.  Is there a cross platform thing that will let me tell the system to poll the USB a lot?
The target I have to do is Win-10/11 but some users may have a Linux system or an apple.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Serial seems to be slow
« Reply #8 on: June 09, 2022, 09:05:55 am »
I'd rather not show the whole code.  Partly because there is a huge amount of code but here is a simple bit of code:

Give us something we can compile or you won't get useful help.

The fact that there's SerRead() etc. suggests that you're using serial.pp: correct?

That was intended to be as close to the OS as possible, and can be used either with or without a background thread... that's why there's the optional callback which isn't needed if threaded.

See examples at https://forum.lazarus.freepascal.org/index.php/topic,58709.msg438286.html#msg438286 noting that these are for unix.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Serial seems to be slow
« Reply #9 on: June 09, 2022, 10:42:58 am »
... here is a simple bit of code:
This appears to be a protocol with one transmitted byte followed by one received byte? This does not fit in nicely with the typical IO buffering at hardware, driver and OS levels.  What is your application's round trip latency requirement?

... Is there a cross platform thing that will let me tell the system to poll the USB a lot?
The target I have to do is Win-10/11 but some users may have a Linux system or an apple.
I don't know of a cross platfdorm way to to change USB polling rate.  On Windows, according to this link you can manually change it in the device driver (for an FTDI device).  I just checked with a CP2102 module and its Windows driver doesn't expose the latency timer setting.  For Linux, read through this discussion.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Serial seems to be slow
« Reply #10 on: June 09, 2022, 12:16:21 pm »
This appears to be a protocol with one transmitted byte followed by one received byte? This does not fit in nicely with the typical IO buffering at hardware, driver and OS levels.  What is your application's round trip latency requirement?

Agreed. If nothing else I'd suggest that this is crying out for two background threads: one to read and one to write, neither with artificial delays.

Quote
I don't know of a cross platfdorm way to to change USB polling rate.  On Windows, according to this link you can manually change it in the device driver (for an FTDI device).  I just checked with a CP2102 module and its Windows driver doesn't expose the latency timer setting.  For Linux, read through this discussion.

I discussed this sort of thing with FTDI a few years ago, and there's a limited amount of latency control etc. exposed at the chip level. In any event, chips sold as FTDI rarely are so the more unusual settings (written to internal EPROM) are unlikely to work as extended, and all bets are off when it comes to other adapters... the CPs, CHs and so on.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

kensmith

  • New Member
  • *
  • Posts: 15
Re: Serial seems to be slow
« Reply #11 on: June 09, 2022, 08:04:49 pm »
.... snipping to comment on one part ...
Agreed. If nothing else I'd suggest that this is crying out for two background threads: one to read and one to write, neither with artificial delays.

This is the exact reverse of what I need  :(
As I explained previously, there is logic that deals with each byte one by one.
The sending of the next byte depends on the receiving of a byte.
I have to get a byte. Look at it. Send the next byte.
I may have to give up on trying to make this cross platform and able to be ported.

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: Serial seems to be slow
« Reply #12 on: June 09, 2022, 09:14:33 pm »
This is the exact reverse of what I need  :(
As I explained previously, there is logic that deals with each byte one by one.
The sending of the next byte depends on the receiving of a byte.
I have to get a byte. Look at it. Send the next byte.
I may have to give up on trying to make this cross platform and able to be ported.
What do you expect from that type of processing? You effectively lose almost everything that can speed up communication:
  • You actually work at half speed since Tx will be idle while checking for incoming byte
  • You can't take advantage of the UART hardware FIFOs
  • You can't take advantage of the UART interrupts processing and OS buffering facilities
  • Polling time at both sides sums up to the transmission time of every single byte transferred, the CPU time isn't 100% dedicated to your program at least at the PC side
  • The USB polling will make things much much worse

Such a protocol with no way to tell what will happen until (every) next byte arrived is rather a funny one. I don't have an idea how one would expect to transfer continuous data, rather than e.g. just a simple command bytes.

I'd suggest to reconsider the protocol, if you are at position to change it (not a legacy one, etc.)
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Serial seems to be slow
« Reply #13 on: June 09, 2022, 09:25:45 pm »
This is the exact reverse of what I need  :(

(Shrug) Suit yourself. There's plenty of ways of integrating traffic from multiple threads into a unified stream or state machine, but you clearly know best.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Serial seems to be slow
« Reply #14 on: June 10, 2022, 07:31:40 am »
.... snipping to comment on one part ...
Agreed. If nothing else I'd suggest that this is crying out for two background threads: one to read and one to write, neither with artificial delays.

This is the exact reverse of what I need  :(
As I explained previously, there is logic that deals with each byte one by one.
The sending of the next byte depends on the receiving of a byte.
I have to get a byte. Look at it. Send the next byte.
I may have to give up on trying to make this cross platform and able to be ported.
This sounds like it will be easier to handle in a microcontroller, where one works close to the hardware latency. If the inspection logic is not too heavy a humble AVR should suffice. Else an ARM or ESP if more computational power is required for the logic. Of course one wants to avoid external hardware dependencies, but if your requirements conflicts with modern computer and OS design...

 

TinyPortal © 2005-2018