Multithreaded throughput test

MTSkull

Centurion
Joined
Mar 25, 2003
Messages
151
Location
Boulder, Colorado
I am trying to create a throughput test. I have two data radios that I need to test at 115200 Baud and need to make sure the data arrives at better then 140000 Baud over a 3 second burst of random byte data. I am creating a randomized array size of Baud Rate * 3seconds, and then measuring the time it takes to get the data back, In addition I compare the data sent to the data received to check for errors.

My current solution takes ~38 seconds to run, so I think part of the bottle neck is currently code based. I used a multithread transmit and receive solution. Where I transmit all of the data in one thread via one com port and then listen on another thread in another com port for the data. Both the TX and RX ports are set to 115200.

Following is the class I use to setup and run the whole thing. What I need to know is can I make this work somehow. Or do I need to scrap this and find another solution. The com ports are USB serial port emulators, which might also be contributing to the problem. I also thought it might be better to write this as a library in C++ for better speed. I have a meeting with the hardware engineers to confirm if the baud rate spec is Bytes or Bits, but since baud rate is typically in symbols per second I think it is bytes. All of the data transmitted between radios is FM modulated ascii.

Thanks as always
MTS

P.S. Keep in mind this is a rough prototype, but I was surprised at how slow it was, so did not want to put more effort into it if not necessary.

Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Threading;
using mts_ErrorConstant;
using mts_RandomNumberGen;
using mts_Utilities;


namespace mts_DataTest
{
    class DataTest
    {
        #region Variables
        private SerialPort txPort;
        private SerialPort rxPort;

        private byte[] txBuffer = new byte[1];
        private byte[] rxBuffer = new byte[1];

        private int baudRate = 0;
        private int secsToTX = 0;
        
        private int bytesToTransmit = 0;
        private int dataErrors = -1;

        private DateTime txStart = DateTime.Now;
        private DateTime rxStop = DateTime.Now;
        private double transitTime = -1; // transit time in seconds


        #endregion

        #region Properties
        //read write properties
        public SerialPort TransmitPort
        {
            get { return txPort; }
            set { txPort = value; }
        }
        public SerialPort ReceivePort
        {   
            get { return rxPort; }
            set { rxPort = value; }
        }
        public byte[] TransmitBuffer
        {
            get { return txBuffer; }
            set { txBuffer = value; }
        }
        public byte[] ReceiveBuffer
        {
            get { return rxBuffer; }
            set { rxBuffer = value; }
        }
        public int BaudRate
        {
            get { return baudRate; }
            set { baudRate = value; }
        }
        public int SecondsToTX
        {
            get { return secsToTX; }
            set { secsToTX = value; }
        }
        
        //read only properties
        public int BytesToTransmit
        {// read only
            get { return bytesToTransmit; }
            //set { bytesToTransmit = value; }
        }
        public int DataErrors
        {
            get { return dataErrors; }
            //set { dataErrors = value; }
        }
        public double TransitTime
        {
            get { return transitTime; }
            //set { transitTime = value; }
        }

        #endregion

        public DataTest()
        {// TODO fill this in


        }
        public DataTest(SerialPort TransmitSerialPort, SerialPort ReceiveSerialPort, int BaudRateToTest, int SecondsToTransmit)
        {
            TransmitPort = TransmitSerialPort;
            ReceivePort = ReceiveSerialPort;

            BaudRate = BaudRateToTest;
            SecondsToTX = SecondsToTransmit;

            bytesToTransmit = BaudRate * SecondsToTX;

            TransmitBuffer = new byte[BytesToTransmit];
            ReceiveBuffer = new byte[BytesToTransmit];

            FillTXBuffer();
        }

        public void FillTXBuffer()
        { // Fill up the transmit buffer with random data 
            RandomNumberGen RandomNum = new RandomNumberGen();
            RandomNum.FillByteArray(txBuffer);
        }

        public Int32 DataThroughPutTest(ref int NumberOfErrors, ref double TransitTimeInSeconds)
        {
            Thread txThread = new Thread(new ThreadStart(TransmitByteData_Threaded));
            Thread rxThread = new Thread(new ThreadStart(ReceiveByteData_Threaded));

            txThread.Start();
            rxThread.Start();

            while (rxThread.IsAlive == true)
            { // add time out code here…
            }

            TimeSpan transTime = rxStop.Subtract(txStart);
            transitTime = transTime.TotalSeconds;

            return ErrorConstant.ERROR_GEN_PASS;

        }

        //Data Test MultiThread Functions
        private void TransmitByteData_Threaded()
        {
            //start the timer
            txStart = DateTime.Now;

            //transmit all data
            txPort.Write(txBuffer, 0, bytesToTransmit);
        }
        private void ReceiveByteData_Threaded()
        {
            string data = "";

            Int32 loopCount = 0;

            // minimize what we do here for speed
            while (data.Length < bytesToTransmit && loopCount < 1000000)
            { // TODO time this instead of a blanket 1mil loop time out
                data += rxPort.ReadExisting();
                loopCount++;
            }

            rxStop = DateTime.Now;

            // proccess the data into an array
            for (int x = 0; x < data.Length; x++)
            {
                rxBuffer[x] = Convert.ToByte(Convert.ToChar(data.Substring(x, 1)));
            }

        }

    }
}
 
Wow must be a tough one.

Couple of updates in case anyone references this in the future.

Baud Rate is Symbol Rate not gross BPS. So all of my calculations are based on symbol rate. After talking to the hardware engineers and them showing me the product fine print it is actually measured as Bits Per Second. So with the serial ports set to 1 start bit, 8 data bits and one space between symbols. We get ten bits per symbol.

I ran the comports through a null modem into each other to check if I was getting any bottlenecks over the USB ports. I consistently measured right at 115200 Bps. I got similar results when I ran one USB port into the native serial port. So with that sorted I intend to introduce the test devices and see how that effects the results. Other then that the above code is a good rough frame work for bit throughput testing with some additional modifications.

Modified above class constructor with...
bytesToTransmit = (BaudRate * SecondsToTX) / 10;

Later
MTS
 
Back
Top