Boost Atomic: кольцевой буфер без ожидания с большим объемом данных

Я хочу использовать boost::atomic для кольцевого буфера без ожидания, как описано здесь:

Пример повышения

мой producer предоставляет большой объем данных одновременно (беззнаковый символ, + — 3000 значений), точно так же, как матрица, которую он будет заполнять построчно. Какой самый лучший способ push эти значения в буфере? Должен ли я просто зациклить их или я могу memcpy их внутри как-нибудь?

То же самое касается pop если я хочу прочитать кучу значений одновременно …


Вот что я придумал, по какой причине это не должно быть хорошо?
Мне просто нужно убедиться RINGBUFFERSIZE % iSize = 0,

#define RINGBUFFERSIZE = 30000

ring_[RINGBUFFERSIZE];

bool push(unsigned char* iData, int iSize)
{
size_t head = head_.load(boost::memory_order_relaxed);
size_t next_head = next(head,iSize);
if (next_head == tail_.load(boost::memory_order_acquire))
return false;
memcpy(ring_+head,iData,iSize);
head_.store(next_head, boost::memory_order_release);
}

bool pop(unsigned char * value, int iSize)
{
size_t tail = tail_.load(boost::memory_order_relaxed);
if (tail == head_.load(boost::memory_order_acquire))
return false;
value = &ring_[tail];
tail_.store(next(tail,iSize), boost::memory_order_release);
return true;
}size_t next(size_t current, int iSize)
{
return (current + iSize) % RINGBUFFERSIZE;
}

1

Решение

Самый быстрый способ — нажать указатель (либо unsigned char * или указатель на некоторую структуру, которая также содержит длину).

Конечно, при условии, что это нормально, чтобы заставить pop если взять те же самые фрагменты, которые были выдвинуты, это просто решает проблему: теперь вам нужно каким-то образом управлять распределением этих буферов.


Простой пример решения для управления вашими чанками:

  1. предварительно выделить «достаточно» объектов чанка фиксированного размера (скажем, динамическая длина + unsigned char data[3096] или что угодно)
  2. отправить адрес чанка в кольцевой буфер без ожидания
  3. отправить адрес назад в другом кольцевом буфере, когда потребитель покончит с ним, поэтому производитель может перезапустить тот же объект чанка

Если вы действительно не можете этого сделать, вы мог выберите максимальный размер для ваших кусков и вставьте / вытолкните объекты этого размера по значению … но, честно говоря, это кажется очень расточительным (даже если объект знает его длину, поэтому не нужно memcpy весь массив 3k для небольших кусков).

1

Другие решения

Других решений пока нет …