Информация об изменениях

Сообщение Re[26]: Эльбрус мёртв, да здравствует Эльбрус-Б! от 03.06.2025 8:10

Изменено 03.06.2025 8:37 vdimas

Re[26]: Эльбрус мёртв, да здравствует Эльбрус-Б!
Здравствуйте, Sinclair, Вы писали:

S>Да, там кокие-то чудеса. На первый взгляд выглядит совершенно как обычный ансейф-код обращения к массиву, минуя проверки диапазона.

S>Зачем они это навертели, вместо простых и понятных манипуляций с указателями в unsafe — х.з.

Чтобы не делать пин при преобразовании к указателю в блоке fixed().
Да, этот пин условно бесплатен для клиентского GC, но не всегда бесплатен для серверного, выполняющего GC в фоне постоянно.


S>И вообще, там много непонятного кода.


Это надо смотреть на сценарии использования.
В аналогичных случаях мне удавалось обходиться без unsafe-блоков кода через библиотечные Unsafe.As<>/Unsafe.Add<>, т.е. через обычные ref int/long/etc ссылки.
Код выглядит как достаточно тупой порт на C# на сегодня.


S>Такое впечатление, что вся эта ансейф-магия в дотнетном дисрупторе нужна для покрытия тех случаев, который джавовский дисруптор не умеет в принципе: когда евенты в очереди лежат не по ссылке, а по значению.


Кстате, раз уж ты дал ссылку на дотнетную реализацию, то там есть, в том числе, реализация поверх unamanaged-буфера. ))
Но опять всё сделано максимально по-нубски, бо можно было сразу хранить типизированный указатель, а не пользовать SafeHandle, т.к. это опять очень внутренний код, т.е. можно было сделать надёжную финализацию в объектах более высокого уровня, наслдуя их от CriticalFinalizerObject, а не получать штраф на лишнюю косвенность. Разрабы этого говнокода явно не понимают, что в отсутствии необходимости вызовов DangerousAddRef/DangerousRelease у объекта SafeHanlde тот не нужен вовсе. ))

И заодно куча ручной разметки:
public abstract class UnmanagedRingBuffer : ICursored
{
    // padding: DefaultPadding

    [FieldOffset(DefaultPadding)]
    protected IntPtr _entries;

    [FieldOffset(DefaultPadding + 8)]
    protected long _indexMask;

    [FieldOffset(DefaultPadding + 16)]
    protected int _eventSize;

    [FieldOffset(DefaultPadding + 20)]
    protected int _bufferSize;

    [FieldOffset(DefaultPadding + 24)]

Что тоже нубство, бо можно было просто описать структуру Padding и пометить класс через LayoutKind.Sequential.

DefaultPadding у них равен 64-8=56, что тоже странно, бо на современных серверных процах бывает размер линейки кеша 128 байт, т.е. эта константа из прошлого.

Да кароч, это я только в 3 файла глянул — две ваших с "точкой" ссылки и еще один из любопытства, и уже без боли смотреть невозможно.

Забейте вы уже на этот Dusruptor, это действительно плохой пример, аминь.
Re[26]: Эльбрус мёртв, да здравствует Эльбрус-Б!
Здравствуйте, Sinclair, Вы писали:

S>Да, там кокие-то чудеса. На первый взгляд выглядит совершенно как обычный ансейф-код обращения к массиву, минуя проверки диапазона.

S>Зачем они это навертели, вместо простых и понятных манипуляций с указателями в unsafe — х.з.

Чтобы не делать пин при преобразовании к указателю в блоке fixed().
Да, этот пин условно бесплатен для клиентского GC, но не всегда бесплатен для серверного, выполняющего GC в фоне постоянно.


S>И вообще, там много непонятного кода.


Это надо смотреть на сценарии использования.
В аналогичных случаях мне удавалось обходиться без unsafe-блоков кода через библиотечные Unsafe.As<>/Unsafe.Add<>, т.е. через обычные ref int/long/etc ссылки.
Код выглядит как достаточно тупой порт на C# на сегодня.


S>Такое впечатление, что вся эта ансейф-магия в дотнетном дисрупторе нужна для покрытия тех случаев, который джавовский дисруптор не умеет в принципе: когда евенты в очереди лежат не по ссылке, а по значению.


Кстате, раз уж ты дал ссылку на дотнетную реализацию, то там есть, в том числе, реализация поверх unamanaged-буфера. ))
Но опять всё сделано максимально по-нубски, бо можно было сразу хранить типизированный указатель, а не пользовать SafeHandle, т.к. это опять очень внутренний код, т.е. можно было сделать надёжную финализацию в объектах более высокого уровня, наследуя их от CriticalFinalizerObject, а не получать штраф на лишнюю косвенность. Разрабы этого говнокода явно не понимают, что в отсутствии необходимости вызовов DangerousAddRef/DangerousRelease у объекта SafeHanlde тот не нужен вовсе. ))

И заодно куча ручной разметки:
public abstract class UnmanagedRingBuffer : ICursored
{
    // padding: DefaultPadding

    [FieldOffset(DefaultPadding)]
    protected IntPtr _entries;

    [FieldOffset(DefaultPadding + 8)]
    protected long _indexMask;

    [FieldOffset(DefaultPadding + 16)]
    protected int _eventSize;

    [FieldOffset(DefaultPadding + 20)]
    protected int _bufferSize;

    [FieldOffset(DefaultPadding + 24)]

Что тоже нубство, бо можно было просто описать структуру Padding и пометить класс через LayoutKind.Sequential.

DefaultPadding у них равен 64-8=56, что тоже странно, бо на современных серверных процах бывает размер линейки кеша 128 байт, т.е. эта константа из прошлого.

Да кароч, это я только в 3 файла глянул — две ваших с "точкой" ссылки и еще один из любопытства, и уже без боли смотреть невозможно.

Забейте вы уже на этот Dusruptor, это действительно плохой пример, аминь.