Skip to content

Bishal-9/FastQueue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FastQueue: High-Performance Single-Producer Multi-Consumer Queue

A lock-free, cache-friendly FIFO queue built on a fixed 10 MB buffer. Designed for minimal synchronization overhead between one producer and one consumer thread or component.


Table of Contents

  • Features
  • Repository Structure
  • API Reference
  • Usage Examples
  • Testing
  • Build & Compilation
  • Performance Considerations
  • License

Features

  • Lock-free single-producer/single-consumer semantics
  • Fixed 10 MB contiguous global buffer for predictable memory usage
  • Cache-line (64 B) alignment of atomic counters and data region to avoid false sharing
  • Header-only implementation
  • C++20 standard library only

Repository Structure

project-root/
├── FastQueue.h      ← Header-only implementation
└── main.cpp         ← Example tests and usage

API Reference

Types

struct FastQueue;
struct QProducer;
struct QConsumer;

Constants

constexpr std::size_t CACHE_LINE_SIZE = 64;                 // CPU cache line size
constexpr std::size_t QUEUE_SIZE      = 10 * 1024 * 1024;   // 10 MB buffer
#define EXPECT(cond, msg) assert((cond) && (msg))           // Runtime checks

FastQueue

struct FastQueue {
    alignas(CACHE_LINE_SIZE) std::atomic<uint64_t> m_read_counter{0};
    alignas(CACHE_LINE_SIZE) std::atomic<uint64_t> m_write_counter{0};
    alignas(CACHE_LINE_SIZE) uint8_t m_buffer[0]; 
};
  • m_read_counter: total bytes published by the producer
  • m_write_counter: total bytes made available
  • m_buffer: raw byte region for enqueued payloads

QProducer

QProducer(FastQueue* queue);
void Write(std::span<std::byte> buffer);
  • Constructor: binds producer to an existing FastQueue in the global buffer
  • Write: atomically appends a 4-byte length header plus buffer.size() payload bytes. Fails via EXPECT if the queue would overflow.

QConsumer

QConsumer(FastQueue* queue);
int32_t TryRead(std::span<std::byte> buffer);
  • Constructor: binds consumer to the same FastQueue
  • TryRead:
    • Returns 0 if no data is available
    • Otherwise reads up to buffer.size() bytes into buffer, returns the actual number of payload bytes read
    • Fails via EXPECT on overflow or insufficient output buffer

Testing

main.cpp includes two basic tests:

  1. basic_test()
    • Verifies single-threaded write/read integrity
  2. thread_test()
    • Launches separate producer and consumer threads
    • Ensures all messages are processed without data loss

Run the tests to validate correctness and thread-safety.


Build & Compilation

Requires a C++20–compliant compiler and pthreads support:

g++ -std=c++20 -O2 -pthread main.cpp -o fastqueue_test
./fastqueue_test

For debug builds with AddressSanitizer:

g++ -std=c++20 -g -fsanitize=address -fsanitize=undefined -pthread main.cpp -o fastqueue_test_debug
./fastqueue_test_debug

Limitations

  • SPMC only (single producer, multi consumer).
  • No circular buffer support (queue grows linearly within allocated memory).
  • Consumer must allocate a large enough buffer for the largest payload.
  • On overflow or insufficient buffer, program aborts due to assert.

Future Improvements

  • Add circular buffer logic for continuous operation.
  • Support multiple producers/consumers with stronger synchronization.
  • Replace assert-based checks with configurable error handling.
  • Add benchmarks for performance testing.

About

FastQueue: High-Performance Single-Producer Multi-Consumer Queue

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors