Hi all, we are having a performance issue with asyn and I am not sure if I am misusing the tool...
So, we have a driver connected to a detector using a 1 Gb/s NIC. To simulate the detector behavior, we created a simple c++ code that opens a socket and generates 1 Gb of packets of 128 bits each. It then sends these packets to the loopback interface.
A simple c++ socket client could read these packets in a bit less than one second with no problem.
(Considering about 40 bytes of TCP+IP overhead, 1Gb of packets would be: (1*10^9)/(128 + 40*8) ≃ 2232143 packets)
We then tried to read from the loopback interface with the driver. It took about 140 seconds to read it! Thats about 7 Mbps or less than 1 MBps if I'm not making any silly mistake.
I then removed everything I could from the driver and left only the read function inside a while(true) loop. The read time reduced to 24 seconds. Better, but still weirdly slow.
Am I doing something wrong or is this asyn read function overhead expected?
About the code:
In the constructor, we connect to the detector via:
drvAsynIPPortConfigure(detectorPortName, detectorIPcmd.c_str(), 0, 1, 0);
// /* Assign that port to the asynUser */
pasynCommonSyncIO->connect(detectorPortName, 0, &pasynUserCommon, "");
pasynOctetSyncIO->connect(detectorPortName, 0, &pasynUserOctet, "");
Then create the acquisition thread:
epicsThreadOpts acqTaskThreadOpts;
acqTaskThreadOpts.priority=epicsThreadPriorityMedium;
acqTaskThreadOpts.stackSize=epicsThreadGetStackSize(epicsThreadStackMedium);
acqTaskThreadOpts.joinable=1;
status = (epicsThreadCreateOpt("acqTask",
(EPICSTHREADFUNC)acqTaskC,
this,
&acqTaskThreadOpts) == NULL);
And inside the acquisition thread:
unsigned char tcp_frame[TCP_FRAME_SIZE];
status = pasynOctetSyncIO->read(pasynUserOctet, (char*)tcp_frame, (size_t)TCP_FRAME_SIZE,
timeout, &nIn, &eomReason);
I also tried improving the thread priority from medium to maximum, but to no avail.
Thanks for any help,
Marco