Previous Entry Share Next Entry
2016-01

640k is enough for everyone

сделал я значит логгер, с сообщениями пронумерованными как int32

и решил показать в дашборде последнее сообщение лога.
запустил, долго думал "где же баг" - вместо номера сообщения какой-то случайный мусор :)

потом осознал, что бага нет, а логгер в тесте

while(true) { log("HELLO") }

выдаёт сколько-то там миллионов RPS и лепить в счетчик int32 было как-то, хмм, опрометчиво, потому что переполняется он мгновенно :) хороший логгер получился, короче.

This entry was originally posted at http://wizzard.dreamwidth.org/472745.html. It has comment count unavailable comments. Please comment there using OpenID.

  • 1
mbr May 16th, 2016
вот поэтому стоит использовать uint32_t везде, где не требуются отрицательные числа явно.

salas May 16th, 2016
Разве это не маскирует баг?

wizzard0 May 16th, 2016
маскирует, да. я оставил знаковое.

mbr May 17th, 2016
Да, маскирует. В любой системе содержатся баги. Основной принцип построения реалтаймовых систем - максимальная отказоустойчивость.

blackyblack May 16th, 2016
Правильней использовать bigint везде, где не требуется максимальная производительность. uint32 так себе панацея. Может автору требовалась уникальность счётчика.

wizzard0 May 16th, 2016
у автора hard realtime, arbitrary precision нет, int64 да, явный детект оверфлоу с выбросом ошибки да.

mbr May 17th, 2016
в си нет bigint. Если идут намеки про uint64_t, то в реалтайме использование его на 32 битной архитектуре не всегда оправдано. И расширение размерности там где это не нужно - это не панацея - это говнокод.

wizzard0 May 17th, 2016
bigint иногда полезен если мы говорим про proof-checked code, в смысле упрощения этих самых proofs, но он вносит кучу своего гемора, например, memory management.

поэтому я лучше буду дефайнить что нода работает не более 2^50 логических тиков, тик у нас хранится в (u)int64, а 50 бит потому что дашборд может быть на JS, где показывать более чем 2^53 это гемор, плюс еще пару бит про запас.

mbr May 17th, 2016
Если ты правда пишешь про жесткий реалтайм и 32 битную систему, то за такое по рукам надо бить. Потому как 64 битное сложение это больше десятка ассемблерных инструкций. 32 битный инкремент в тиках с переполнением. При флаге переполнения инкремент старшего счетчика. Если использовать ассемблер, оверхед в 1 инструкцию. Генерация 64 битного значения из 2х32 на прикладном уровне.

wizzard0 May 17th, 2016
64бит. 32бит не поддерживаем.

(да, я в курсе что cache miss-ы могут очень даже джиттерить этот реалтайм, и tlb тоже добавляет к джиттеру, и т.д. но хватает. а 4 гб RAM не хватает)

Edited at 2016-05-17 06:33 pm (UTC)

mbr May 17th, 2016
А на кой ты тогда явно указывал индекс 32 битный? Это может привести к неэффективной работе конвеера.

wizzard0 May 17th, 2016
потому что в куске кода который на другой машине (не реалтаймовой) исполняется были проблемы с 64бит )) в смысле местами кое-чего тупо недописано

Edited at 2016-05-17 08:02 pm (UTC)

Google C++ Style Guide, On Unsigned Integers

bik_top May 16th, 2016
> вот поэтому стоит использовать uint32_t везде, где не требуются отрицательные числа явно.

«So, document that a variable is non-negative using assertions. Don't use an unsigned type.»

Re: Google C++ Style Guide, On Unsigned Integers

mbr May 17th, 2016
Во первых про кресты никто не говорил. Во вторых растет все это от говнокода базовых библиотек анси. Ну вот лень было писать unsigned. В третьих срать на какие-то там принципы какой-то корпорации, если это противоречит здравому смыслу.

Re: Google C++ Style Guide, On Unsigned Integers

wizzard0 May 17th, 2016
говнокод базовых библиотек кстати приносит очень много боли и он по-моему везде. вопрос вменяемой эволюции API никто так толком и не решил :( хотя казалось бы - системы с обеих сторон формализуемы по самое немогу, спрос на такое тоже есть, в какое-то IDE под капот упихивается замечательно, в отдельный линтер - тоже, etc, etc.

Re: Google C++ Style Guide, On Unsigned Integers

mbr May 17th, 2016
Гыг. Добро пожаловать в наш мир :)

wizzard0 May 16th, 2016
э, а чем мне uint32 поможет от переполнения? о_О

mbr May 17th, 2016
От переполнения нет, но от математики, где число, "внезапно" превращается в отрицательное - вполне. Из серии if (a > 5) проавалится если a будет отрицательным из-за переполнения.

109 May 16th, 2016
кстати, да. какого хрена массивы нумеруются интом, а не юинтом?

wizzard0 May 16th, 2016
да что тут все за знаковость вцепились? чем беззнаковость помогает от оверфлоу?

109 May 17th, 2016
я-то не про оверфлоу, а про про то, чтобы правильные типы использовать. а знаковый инт, я так полагаю, растёт с того времени, когда возврат -1 из функций типа findIndex использовался для индикации "не нашли". сейчас бы, небось, использовали Option[T], если бы дизайнили с нуля.

mbr May 17th, 2016
+

wizzard0 May 17th, 2016
мне кажется, что массивы нумеруются интом с тех пор, как они были pointer arithmetic.

ну и еще в языках повысокоуровневее любят отрицательными индексами с конца считать.

mbr May 17th, 2016
А вот отучайся от такого. На нижнем уровне там нет проверки, сдвиги и ассемблер. Что почти гарантированно приведет к bus fault.

wizzard0 May 17th, 2016
это да.

109 May 17th, 2016
эмм... а как pointer arithmetic помогает обосновать знаковость?

wizzard0 May 17th, 2016
имеется в виду, что ptrdiff_t знаковый

juan_gandhi May 16th, 2016
Сказывается сишный опыт.
Я б просто поставил, скажем, 36-base числа, в виде строк, их бесконечное количество.
Ну в смысле я уже такое поставил в одном месте.

wizzard0 May 16th, 2016
мнэээ, у меня hard realtime, там нельзя arbitrary precision по определению

juan_gandhi May 16th, 2016
Ну тогда, конечно, по модулю - остается только выбрать нужный модуль. В вашем риалтайме реальной время с календаря тоже запрещено? Ведь оно не ограничено (кроме как жизнью вселенной).

wizzard0 May 16th, 2016
запрещено, да. потому что сисколл чтобы прочитать системное время - дорогой слишком :)

а так-то там нода работает ограниченное время и потом ее recycle'ят, и на это время где-то 35 бит из int64 логического времени должно хватить.

juan_gandhi May 17th, 2016
А, вот и подошли к реалистической модели.

blackyblack May 17th, 2016
Время с календаря не гарантирует уникальности этого "счётчика".

vaddimka May 17th, 2016
Делал недавно что-то такое с циклическим буфером на мегабайт и произвольной длиной сообщения, кстати надо посмотреть, вставил ли я туда счетчик. Туда же всунул опциональную регистрацию всех сообщений из данного c файла под определенным именем модуля и логлевел. Вообще интересно иногда на чистых сях писать, столько всего руками поделать можно.

mbr May 17th, 2016
Каноническая реализация кольцевых буферов подразумевает размеры 2^n и маску 2^n - 1, что превращает переполнение из головной боли в фичу.

vaddimka May 17th, 2016
Я помню что самый большой геморрой был это когда данные "заворачиваются" за конец буфера, учитывая что сообщения произвольной длины получается достаточно нетривиально рассчитать все позиции включая заголовок, длину сообщения, само сообщение. Так-то оно вроде тривиально, но если не делать что-то типа "о, оно не помещается целиком, давай завернем", я в итоге убил часа четыре )

mbr May 17th, 2016
Изначально кольцевые буферы использовались для символьных устройств - т.е. когда размер данных одинаков. В случае разной длины лучше использовать указатели на структуру или выбрать другую модель реализации. Например, гугловские bip буферы.

wizzard0 May 17th, 2016
...или делать буфер блоков

mbr May 17th, 2016
Не. Медленно, геморройно, фрагментация.

wizzard0 May 17th, 2016
я имею в виду случай, когда сообщение переменного, но конечного размера.

если бесконечного, тогда да, гемор всегда

amarao_san May 17th, 2016
Очередной дефицит натуральных чисел. Хотя казалось бы, выдали человечеству бесоконечность - но её постоянно не хватает.

wizzard0 May 17th, 2016
ну, э. мне надо за конечное время пакет обработать...

maxim May 17th, 2016
У нас везде Bigint в бизнес-объектах, слава буддам вкатили GMP в Erlang на его заре.

wizzard0 May 17th, 2016
так там и не реалтайм)

  • 1
?

Log in

No account? Create an account