OS : VxWorks 22.09
Project Type : Real Time Process (RTP)
CPU : Intel 11th Generation i7-1185GRE (4 CPU 8 Threads)
I'm working on a Hard Real Time low latency system.
I have a Single Producer Single Consumer problem.
Data is produced by the callback function on the read thread (Ethernet and Serial Ports threads).
The data is consumed by main thread.
Pseudo Code :
typedef struct EthernetData
{
std::string ip;
std::uint16_t portNumber;
std::string data;
}ethernet_data_t;
std::queue<ethernet_data_t> ethernet_queue;
boost::lockfree::spsc_queue<ethernet_data_t, boost::lockfree::capacity<10> > spsc_queue;
Ethernet Callback
void on_receive_ethernet(const std::string &ip, std::uint16_t portNumber, const std::string &data)
{
ethernet_data_t data {ip, portNumber, data};
ethernet_queue.push(data)
}
Main Thread
void run(void)
{
while(1)
{
if(ethernet_queue.empty() == false)
{
//Process Ethernet Data
}
if(SerialPort1_queue.empty() == false)
{
//Process SerialPort1 Data
}
if(SerialPort2_queue.empty() == false)
{
//Process SerialPort2 Data
}
...
}
}
I am inclining towards boost::lockfree::spsc_queue after reading the bellow
Performance of Non-Blocking Data Structures
Lock-free data structures will be a better choice in order to optimize the latency of a system or to avoid priority inversion, which may be necessary in real-time applications. In general we advise to consider if lock-free data structures are necessary or if concurrent data structures are sufficient. In any case we advice to perform benchmarks with different data structures for a specific workload.
I have few questions:
- Will the boost::lockfree::spsc_queue use atomic instruction instead of guards for complex data type like structure defined above for boost::lockfree::spsc_queue? I ask this because the lock free documentation states
Instead of relying on guards, non-blocking data structures require atomic operations (specific CPU instructions executed without interruption)
. - In the answer https://stackoverflow.com/a/53854518/6319901, it states in single producer and singe consumer don't need mutex. If I just check if the queue is empty in main thread in side the while loop (without mutex) will it work or will I suffer some synchronization problem. If not wouldn't it be preferable to use std::queue without any guards (mutex)
- I have on an average 5 such queues on each RTP. I have 6 such RTPs. Will this cause any performance bottleneck.
- Is checking queue if empty inside while loop advisable. I chose this design pattern to avoid latency.
- Is their any better alternatives available?
Aucun commentaire:
Enregistrer un commentaire