powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lock-free кольцевой буфер.
15 сообщений из 15, страница 1 из 1
Lock-free кольцевой буфер.
    #39926872
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На просторах интернета встретилось несколько реализаций на Delphi. И даже на любимом sql.ru. Но все они показались мне замороченные и если честно очень длинные, хотя возможно и быстрые.
У меня же задача простая. Есть 1 поток писатель и 1 поток читатель. Буфер создается заранее и заполняется массивами TidBytes.
Если писатель быстрее читателя или наоборот, то ждем.
Так как я еще тот синхронизатор/оптимизатор, то подскажите свежим взглядом, где могут быть ошибки чтения/записи в буфер?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
TLockFreeQueue = class
    private
      FHead: Int64;
      FTail: Int64;
      FSize: int64;
      FItems: array of TPacket;
    public
      function PushObject(AData: TidBytes; ASize: integer): boolean;
      function PopObject(): TPacket;
      constructor Create(const ASize: integer);
      destructor Destroy(); override;
    end;

constructor TLockFreeQueue.Create(const ASize: integer);
var
  i: integer;
begin
  FHead:= 0; //заполняет писатель
  FTail:= 0; //заполняет читатель
  FSize:= ASize;
  SetLength(FItems, ASize);
  for i := Low(FItems) to High(FItems) do
  FItems[i]:= TPacket.Create(UDP_PACKET_SIZE);
end;

destructor TLockFreeQueue.Destroy;
var
  i: integer;
begin
  try
    for i := Low(FItems) to High(FItems) do
    FItems[i].Free;
    FItems:= nil;
  finally
    inherited;
  end;
end;

function TLockFreeQueue.PushObject(AData: TidBytes; ASize: integer): boolean;
var
  Next: integer;
begin

  Next:= TInterlocked.Read(FHead)+1;

  if Next >= FSize then Next:= 0;

  if Next = TInterlocked.Read(FTail) then
  begin
    Result:= False;
    Exit;
  end;

  CopyTIdBytes(AData, 0, FItems[FHead].PackUDP, 0, ASize);
  FItems[FHead].Size:= ASize;

  TInterlocked.Exchange(FHead, Next);
  Result:= True;
end;

function TLockFreeQueue.PopObject(): TPacket;
var
  Next: integer;
begin

  if (TInterlocked.Read(FHead) = TInterlocked.Read(FTail)) then begin
    Result := nil;
    Exit;
  end;

  Next:= TInterlocked.Read(FTail)+1;

  if Next >= FSize then
  Next:= 0;

  Result:= FItems[FTail];
  TInterlocked.Exchange(FTail, Next);
end;
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926877
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вашу проблему решает уже готовый

http://docwiki.embarcadero.com/Libraries/Rio/en/System.Generics.Collections.TThreadedQueue

при этом он решает еще и задачу несколько читают, несколько пишут.
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926890
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
все так. так и использую на текущий момент. Но скорости не хватает. В целом архитектура такая: Один писатель и куча читателей.
Для каждого читателя отдельная очередь с писателем. И такое чувство, что читатели через крит. секции притормаживают писателя, а мне это совсем не нравиться
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926893
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite
Вашу проблему решает уже готовый
http://docwiki.embarcadero.com/Libraries/Rio/en/System.Generics.Collections.TThreadedQueue
при этом он решает еще и задачу несколько читают, несколько пишут.
Только там до Токио включительно, был баг в методе Grow
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926901
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrb
где могут быть ошибки чтения/записи в буфер?
При наличии более одного читателя или писателя ошибки гарантированы

TInterlocked.Exchange для одного читателя/писателя не имеет смысла, для нескольких смотри выше

TInterlocked.Read вообще бессмысленен.
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926902
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrb
все так. так и использую на текущий момент. Но скорости не хватает. В целом архитектура такая: Один писатель и куча читателей.
Для каждого читателя отдельная очередь с писателем. И такое чувство, что читатели через крит. секции притормаживают писателя, а мне это совсем не нравиться

Монитор написан так, что если вы бесконечно пишете и читаете то критическая секция никогда не сработает. Там первые вроде 50 циклов/тактов проверка на ожидание как раз фрилоковая, а потом чтобы не нагружать процессор уже блокировка.
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926904
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,бесконечно пишете и читаете то критическая секция никогда не сработает. В смысле? А как же синхронизация?
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926905
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос не совсем по теме. А никто не знает какая пропускная способность сокета UDP?
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926907
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbВ целом архитектура такая: Один писатель и куча читателей.
Для каждого читателя отдельная очередь с писателем. И такое чувство, что читатели через
крит. секции притормаживают писателя

Это для UDP? Какая-то вывернутая наизнанку архитектура. Обычно бывает наоборот: один поток
только и делает что читает из сокета, а все остальные в него пишут, даже не
синхронизируясь, ибо blocking mode.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926913
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov, мне нужно читать только. Я одним потоком считываю с сокета данные и передаю в другие, которые уже собирают из пакетов конфетку
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926914
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
просто я называю поток, который читает из сокета ПИСАТЕЛЕМ своего буфера
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39926921
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда lock-free алгоритмы тебе не только не нужны, но и полностью противопоказаны,
поскольку приводят к процессорному голоданию producer-а.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39927010
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrb, Для каждого читателя отдельная очередь с писателем.для синхры достаточно одного boolean без interlockИ такое чувство, что читатели через крит. секции притормаживают писателяну,Если писатель быстрее читателя или наоборот, то ждем.и как ты ждёшь?
(если ждёшь, то это уже не Lock-free)



И такое чувствосделай чтобы это было не чувство, а реальные цифры



Я одним потоком считываю с сокета данные и передаю в другие, которые уже собирают из пакетов конфеткуЕсли цена передачи данных между потоками соизмерима со сбором конфетки, то можно ускориться в разы используя пул потоков считывателей из сокета (например, IOCP) внутри которых и будет обработка.
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39927119
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Bred eFeM#22080498]и как ты ждёшь?
В первом посте вроде понятно. Кто быстрее тот и ждет.

IOCP надо попробовать
...
Рейтинг: 0 / 0
Lock-free кольцевой буфер.
    #39927136
pvv.pas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cptngrb,

В комплекте black shark есть коллекция TQueueFIFO<T> для пары потоков отлично работает без использования системных средств синхронизации. Но я использовал только для асинхронной очереди, т.е. с возможностью потерь в случае переполнения. Синхронный режим возможно не будет работать, хотя опция есть. Посмотрел код, как по мне - доработать не проблема.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lock-free кольцевой буфер.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]