[00:00:25] <OCTAGRAM> глюки
[00:00:37] <OCTAGRAM> это -gnatN -gnatp
[00:01:09] <OCTAGRAM> -gnatN инлайн на фронтенде (GNAT), -gnatn инлайн на бекэнде (GCC)
[00:01:39] <OCTAGRAM> последний раз, когда я думал, что -gnatN типа лучше, компилятор убедил меня в обратном
[00:01:54] <OCTAGRAM> им просто никто давно не занимается, похоже
[00:02:04] <OCTAGRAM> -gnatp отключить все проверки
[00:02:45] <ada_ru> (I_vlxy_I) там просто вот такие опции:
gnatmake -O3 -fomit-frame-pointer -march=native -msse3 -mfpmath=sse -gnatNp -f fannkuchredux.adb -o fannkuchredux.gnat-3.gnat_run
[00:03:28] <OCTAGRAM> -ffast-math
[00:03:30] <ada_ru> (I_vlxy_I) ага, таки чтобы хоть как-то сравняться по производительности с плюсами, нужно все проверки отрубить
[00:03:38] <OCTAGRAM> -gnatNp => -gnatnp
[00:03:48] <OCTAGRAM> ну да
[00:04:36] <ada_ru> (I_vlxy_I) -ffast-math -- это же про плавающую точку. то есть такое в принципе не рекомендуют юзать
[00:04:45] <ada_ru> (I_vlxy_I) по крайней мере в плюсах - точность будет не предсказуемая
[00:04:58] <ada_ru> (I_vlxy_I) впрочем, на данный бенч это вообще не должно влиять
[00:05:28] <ada_ru> (I_vlxy_I) интересно насколько большие просадки из за проверок
[00:06:18] <OCTAGRAM> в CCured до 20% вроде пишут
[00:07:15] <OCTAGRAM> или откуда-то из другого места коэффициент 1,2 запомнился
[00:09:46] <OCTAGRAM> если проверять адские контракты типа (for all, то можно некисло просадить
[00:10:56] <ada_ru> (I_vlxy_I) думаю зависит от задачи. можно в разы просесть если это матрицы какие
[00:11:06] <ada_ru> (I_vlxy_I) или еще какая алгоритмика
[00:11:28] <ada_ru> (I_vlxy_I) с санитайзером иногда бывает, по слухам 10x тормоза
[00:11:48] <OCTAGRAM> санитайзер работает не как Ада, я так понимаю
[00:12:37] <OCTAGRAM> на Эльбрусе, пишут, полтора раза в этом их режиме
[00:22:29] <OCTAGRAM> в общем, если без паранойи, то до полутора и это вполне приемлемо держать в продакшн на постоянной основе
[00:23:37] <ada_ru> (I_vlxy_I) ну это если аппаратное
[00:23:52] <ada_ru> (I_vlxy_I) если программное, то просадка сильно будет зависеть от приложение
[00:24:11] <ada_ru> (I_vlxy_I) если твое приложение какая-нибудь субд, то просадки могут быть в десятки раз.
[00:25:12] <OCTAGRAM> поставить, что ли для почтового сервера https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/cheri-qemu.html
[00:26:15] <OCTAGRAM> или что там есть в репозитории CheriBSD
[01:53:36] <ada_ru> (I_vlxy_I) а как будет в аде вектор строк? (строки все разной длины, а вектор - это такой массив на стероидах, который может расти эффективным образом)
[02:13:34] <OCTAGRAM> Indefinite_Vectors (String) или Vector (Unbounded_String)
[02:27:00] <ada_ru> (I_vlxy_I) а технически это будет массив пар указатель на начало строки + длина строки?
[02:27:50] <OCTAGRAM> в AWS контейнерах для параметров и заголовков, например, одно время была запись, дискриминированная длиной ключа и значения, и так они там, ключ и значение, слипшиеся, внутри и сидят, а потом переделали в пару из двух Unbounded_String
[02:29:36] <OCTAGRAM> Unbounded_String имеет один указатель на структуру, в которой счётчик ссылок, ёмкость, длина и данные
[02:30:47] <OCTAGRAM> Indefinite_Vector, есть подозрение, что, не имея представления о содержимом, будет работать через жирные указатели, в которых первый указатель на данные, второй на метаданные
[02:31:26] <ada_ru> (I_vlxy_I) А String (технически) это что такое?
[02:31:49] <OCTAGRAM> последовательность октетов
[02:32:17] <ada_ru> (I_vlxy_I) а, то есть прям таки памяти кусок?
[02:32:26] <OCTAGRAM> да
[02:32:28] <ada_ru> (I_vlxy_I) оно как-то терминировано?
[02:32:35] <OCTAGRAM> нет
[02:32:39] <ada_ru> (I_vlxy_I) или там длина может где-то есть?
[02:32:52] <OCTAGRAM> нет, длина в метаданных
[02:33:22] <OCTAGRAM> данные и метаданные живут разной жизнью
[02:34:06] <ada_ru> (I_vlxy_I) хм. а как? вот у меня String, где метаданные будут? где-то рядышком? а если String прибили, то метаданные тоже умрут?
[02:34:08] <OCTAGRAM> если про строку известно, что это String (1 .. 3), то константы в инструкции могут быть зашиты
[02:35:07] <OCTAGRAM> а если надо этот String (1 .. 3) передать куда-то, где ожидается любой String, то так уж и быть, надо (1, 3) на стеке сделать и передать ссылкой на метаданные
[02:35:33] <ada_ru> (I_vlxy_I) у меня String будет извне приходить. считай что из файла
[02:35:41] <ada_ru> (I_vlxy_I) так что длина - не известна на этапе компиляции
[02:36:26] <OCTAGRAM> будет отдельная, значит, запись для метаданных
[02:36:48] <OCTAGRAM> где-то рядом, но без конкретики
[02:36:59] <ada_ru> (I_vlxy_I) то есть выходит, что куда ни сложи хоть в String, хоть в Unbounded_String, получится, по факту, одинаковая структура хранения? пачка данных + структура с метаданными
[02:37:36] <OCTAGRAM> в Unbounded_String метаданные жёстко перед строкой, и они по указателю
[02:37:49] <OCTAGRAM> а String лежит на месте, без указателей
[02:38:35] <OCTAGRAM> если new String ещё сделать, тогда метаданные тоже жёстко прибиты перед данными
[02:38:42] <ada_ru> (I_vlxy_I)  отвечает на <(OCTAGRAM) в Unbound…>
перед строкой лежит указатель на метаданные, или сами метаданные?
[02:39:26] <OCTAGRAM> в Unbounded_String поля записи
[02:39:39] <OCTAGRAM> в исходниках так
[02:40:11] <OCTAGRAM> может порядок и другой быть это просто библиотечный пакет, запроганный определённым образом
[02:40:25] <ada_ru> (I_vlxy_I) ну, это понятно
[02:40:30] <OCTAGRAM> метаданными зря назвал поля
[02:40:48] <OCTAGRAM> просто длина одним полем
[02:41:19] <ada_ru> (I_vlxy_I) указатель на данные (собственно текст) другим?
[02:41:19] <OCTAGRAM> о, вот, кстати, там в реализации Unbounded_String получается, что начало всегда в 1
[02:41:45] <OCTAGRAM> нет, там прямо в запись данные вмонтированы
[02:42:47] <OCTAGRAM> там String внутри
[02:43:03] <ada_ru> (I_vlxy_I) type Unbounded_String is new AF.Controlled with record
     Reference : String_Access := Null_String'Access;
     Last      : Natural       := 0;
  end record;
[02:43:08] <ada_ru> (I_vlxy_I) или я куда-то не туда смотрю?
[02:43:22] <ada_ru> (I_vlxy_I) https://github.com/bathtub/llvm-gcc/blob/15454402ee0d98f7e862eef67c5f6e8056928ee8/gcc/ada/a-strunb.ads#L393
[02:43:44] <OCTAGRAM> это доисторическая версия без счётчика ссылок
[02:44:25] <ada_ru> (I_vlxy_I) ну, счетчик ссылок мне не нужен, но я понял, что да, надо новее глянуть
[02:44:30] <OCTAGRAM> https://gcc.gnu.org/viewcvs/gcc/trunk/gcc/ada/libgnat/?dir_pagestart=100
[02:47:33] <OCTAGRAM> https://gcc.gnu.org/viewcvs/gcc/trunk/gcc/ada/libgnat/a-strunb__shared.ads?view=markup
[02:48:06] <OCTAGRAM> type Shared_String (Max_Length : Natural) is limited record ... Data : String (1 .. Max_Length); end record;
[02:48:13] <ada_ru> (I_vlxy_I) https://github.com/gcc-mirror/gcc/blob/gcc-8_3_0-release/gcc/ada/libgnat/a-strunb__shared.ads#L472
[02:48:21] <ada_ru> (I_vlxy_I) ой.
[02:48:31] <ada_ru> (I_vlxy_I) type Unbounded_String is new AF.Controlled with record
     Reference : not null Shared_String_Access := Empty_Shared_String'Access;
  end record;
[02:48:49] <ada_ru> (I_vlxy_I) ну, типа указатель на данные же. нет?
[02:49:15] <ada_ru> (I_vlxy_I) точнее на структурку
[02:49:22] <OCTAGRAM> на запись
[02:49:23] <ada_ru> (I_vlxy_I) https://github.com/gcc-mirror/gcc/blob/gcc-8_3_0-release/gcc/ada/libgnat/a-strunb__shared.ads#L433
[02:49:27] <ada_ru> (I_vlxy_I) вот эту
[02:49:38] <OCTAGRAM> а дальше указателей нет
[02:49:44] <OCTAGRAM> дальше всё на месте
[02:49:56] <ada_ru> (I_vlxy_I) переменной длины
[02:51:18] <OCTAGRAM> длина переменная, а кортеж (начало, конец), который нужен, чтоб вызвать функцию от String, явным образом не хранится
[02:52:42] <ada_ru> (I_vlxy_I) ну, начало там Data, а конец это Last
[02:52:44] <OCTAGRAM> не прилеплено ни слева, ни справа, вообще нигде нет того, что называется метаданными, как в жирном указателе
[02:52:44] <ada_ru> (I_vlxy_I) по факту
[02:53:08] <ada_ru> (I_vlxy_I) точнее Last - значимая длина, вот
[02:53:26] <OCTAGRAM> в жирном указателе и при передаче String есть конкретный жёсткий формат метаданных
[02:53:28] <ada_ru> (I_vlxy_I) я, кажется, более-менее понял как оно в памяти лежит, спасибо
[02:53:46] <OCTAGRAM> вот именно в таком формате не хранится
[02:54:29] <ada_ru> (I_vlxy_I)  отвечает на <(OCTAGRAM) в жирном …>
а какой? вот сказал я X : String := ReadLine; -- хз можно так, или нет
[02:54:39] <ada_ru> (I_vlxy_I) что будет? как оно в памяти ляжет?
[02:55:25] <OCTAGRAM> в таком виде для метаданных однозначно будет слот подходящего формата
[02:55:39] <OCTAGRAM> где компилятору удобно, там и положит
[02:56:39] <OCTAGRAM> вот есть в одном блоке объявления переменных, допустим, не один, а несколько таких String, так метаданные к ним можно вместе сложить, потому что фиксированного размера, а данные размещать постепенно
[02:56:57] <OCTAGRAM> так проще адресовать
[02:57:24] <OCTAGRAM> на усмотрение транслятора многое
[02:57:53] <ada_ru> (I_vlxy_I) А ели я сразу скажу Insert(My_Vector, 0, ReadLine); что где будет?
[03:00:03] <OCTAGRAM> Get_Line вернёт на вторичный стек, со вторичного скопируется на основной, на вторичном освободится, потом Insert сделает new String, и скопирует с основного стека в динамическую память, вернётся, после возврата строка на основном стеке освободится
[03:00:29] <OCTAGRAM> new String размещает так, что метаданные перед данными
[03:01:41] <OCTAGRAM> метаданные про строку на вторичном стеке могут быть размещены на основном стеке
[03:02:07] <OCTAGRAM> метаданные про строку на основном стеке практически наверняка будут тоже на основном
[03:04:25] <ada_ru> (I_vlxy_I) выглядит не очень эффективно. три копирования по сути (первое - из системы во вторичный стек)
[03:05:05] <OCTAGRAM> Unbounded_IO.Get_Line эффективнее с этой точки зрения, да
[03:05:27] <OCTAGRAM> если сразу знать, что строку будут в вектор класть
[03:05:57] <OCTAGRAM> то и вектор тогда сразу от Unbounded_String
[03:06:39] <OCTAGRAM> но если нет, то может получиться, что зря надавили на динамическую память, которая тоже чего-то стоит
[03:06:43] <ada_ru> (I_vlxy_I) а есть такой Unbounded_String, который без счетчика? ибо счетчик -- он явно атомик, а это конкретно просадит производительность в многоядерной системе, особенно если это отдельные чипы
[03:06:55] <OCTAGRAM> почему?
[03:07:30] <ada_ru> (I_vlxy_I) атомик блокирует все ядра, сколь я помню. или что-то страшное с кешом делает
[03:07:44] <OCTAGRAM> у кеша есть модель MESI
[03:08:11] <OCTAGRAM> M -> Modified, E -> Exclusive, S -> Shared, I -> Invalidated
[03:08:51] <OCTAGRAM> если с данными работает одно ядро, оно там между M и E должно перегоняться
[03:09:10] <OCTAGRAM> вот из S в E забрать, да, это только через остальные ядра
[03:09:49] <OCTAGRAM> но откуда у остальных ядер линия кеша для той же памяти просто так возьмётся
[03:10:18] <OCTAGRAM> String можно в Ada.Containers.Holders положить ещё, но тогда Insert, Delete и т.п. не будет
[03:10:59] <ada_ru> (I_vlxy_I) попробую найти статью
[03:13:31] <OCTAGRAM> Android на трассирующей сборке мусора, лишний раз не щёлкающей счётчиками, по потребительским качествам уступает iOS, где весь Foundation и UIKit на счётчиках ссылок
[03:14:59] <OCTAGRAM> да, я бы ознакомился, не могу иначе понять, как это сочетается с MESI
[03:15:48] <OCTAGRAM> для того и делали MESI, чтоб могли ядра уединяться с данными и никому не отчитываться, что они там с ними делают, пока остальные не видят
[03:16:11] <ada_ru> (I_vlxy_I) там инструкция lock генерится. (для x86_64)
[03:16:18] <ada_ru> (I_vlxy_I) которая заставляет все ядра пообщаться
[03:16:49] <OCTAGRAM> то есть, проблема специфична для x86_64?
[03:22:39] <ada_ru> (I_vlxy_I) для NUMA архитектуры в принципе, как я понимаю.
[03:22:54] <ada_ru> (I_vlxy_I) хотя может и зря я тут приплетаю нуму
[03:25:20] <OCTAGRAM> я что-то такое уже слышал от Вадима Годунко, но не смог получить разумного объяснения
[03:28:04] <ada_ru> (I_vlxy_I) нарою хоть какие экспериментальные подтверждения - кину сюда ссыль
[03:28:40] <ada_ru> (I_vlxy_I) атомики бывают настолько плохи когда ядер много, что переходят на мьютексы
[03:28:43] <ada_ru> (I_vlxy_I) они дешевле
[03:30:13] <OCTAGRAM> разве мьютекс не пытается атомик поменять внутри себя
[03:37:19] <ada_ru> (I_vlxy_I)  отвечает на <(OCTAGRAM) разве мью…>
вроде бы нет. или не обязательно
[03:37:23] <ada_ru> (I_vlxy_I) https://youtu.be/rJWSSWYL83U?t=11m9s
[03:37:26] <ada_ru> (I_vlxy_I) вот
[03:37:51] <ada_ru> (I_vlxy_I) (там вообще чуть ранее как раз рассказ о том, почему COW строки это плохо и почему атомики в строках - это тормоза)
[03:40:57] <OCTAGRAM> спасибо
[03:41:38] <OCTAGRAM> трижды копировать лучше, чем COW?
[03:42:39] <ada_ru> (I_vlxy_I) лучше мувать и иметь small string optimization
[03:43:02] <ada_ru> (I_vlxy_I) COW это хорошо, но в редких случаях
[03:43:20] <ada_ru> (I_vlxy_I) если интересно - посмотри чуть больше этого видео. Лучше чем Антон я не расскажу.
[03:57:23] <OCTAGRAM> хм, да 5-20 раз для атомика вообще фигня
[03:57:31] <OCTAGRAM> я-то уж подумал
[03:59:57] <OCTAGRAM> посмотрю, но пока что скорее успокоился
[04:00:08] <OCTAGRAM> MESI работает, всё хорошо
[04:04:53] <OCTAGRAM> с move сравнивать не буду
[08:39:42] <ada_ru> (Gourytch)  отвечает (Gourytch) на <#EYECATCHER
оставлю …>
и даже адакор решил больше не учить. ( https://www.ada-ru.org/files/bot/2019-03-02-x10.jpg
[09:38:17] <ada_ru> (Максим) Они просто сменили платформу на https://learn.adacore.com/
[09:39:17] <ada_ru> (Максим) @I_vlxy_I ты решил сортировку на Аде сделать? 😉
[11:51:11] <OCTAGRAM> Почитал документацию по CHERI. Там, оказывается, обычные инструкции MIPS неявно работают с ambient capability, а в расширениях CHERI явно присутствуют capability. Если ambient capability спроецировать на всю виртуальную память, то получается просто MIPS64, расширения которого не обязательны к использованию. Чтобы покрыть процесс защитой, есть ключик компоновщика, который скажет операционной системе не инициализировать ambient capability. Тогда смотреть в память можно будет только через такие capability, которые получены законным путём. Короче, понятно, что это FreeBSD с кучей портов, но все эти порты для MIPS64, и без какой-либо повышенной аппаратной защиты.
[11:53:35] <OCTAGRAM> capability = жирный указатель в терминах CHERI, аналог дескриптора в терминах Эльбрус-2000
[14:19:28] <ada_ru> (I_vlxy_I)  отвечает (Максим) на <@I_vlxy_I ты решил с…>
ну, попробовать хотя бы наивный вариант сделать
[14:19:41] <ada_ru> (I_vlxy_I) наивная реализация утилиты sort на аде
[14:22:04] <ada_ru> (Максим) Как строки байт?
[14:22:37] <ada_ru> (I_vlxy_I) угу. простейший вариант. как LC_ALL=C sort
[16:58:25] <ada_ru> (Максим) Ну если с байтами, то у меня получилось как-то так: http://www.ada-ru.org/editor.html?id=azUXXgo9ImMNPc2ZWcePhg==
[17:01:55] <ada_ru> (Максим) тормоза, конечно, по сравнению с sort:
[17:02:05] <ada_ru> (Максим) max@untu:~/net/matreshka$ time /tmp/sort/obj/main ./data/UCA/7.0.0/CollationTest/CollationTest_SHIFTED.txt /tmp/sorted.txt
0.007258000
0.018679000
0.614418000
0.628451000

real    0m0,636s
user    0m0,620s
sys    0m0,016s
max@untu:~/net/matreshka$ time LANG=C sort -o /tmp/sorted2.txt ./data/UCA/7.0.0/CollationTest/CollationTest_SHIFTED.txt

real    0m0,045s
user    0m0,028s
sys    0m0,029s
[17:30:09] <ada_ru> (Максим) есть ещё вариант для матрёшки
[17:30:14] <ada_ru> (Максим) 0.076279000
0.175600000
0.597985000
0.676227000
[17:30:59] <ada_ru> (Максим) он честно работает с юникодом
[17:33:56] <ada_ru> (Максим) Он дольше читает/пишет, но быстрее сортирует
[17:47:27] <ada_ru> (I_vlxy_I) С мобилки кода не видать
[17:49:18] <ada_ru> (I_vlxy_I) Потом с компа гляну
[17:49:54] <ada_ru> (I_vlxy_I) Ну и входной текст маловат. Надо хотя бы гиг строк
[17:50:14] <ada_ru> (I_vlxy_I) Точнее текста
[17:57:14] <ada_ru> (I_vlxy_I) Иначе тест не показателен.
[23:57:40] <OCTAGRAM> я так понимаю, в AWS стандартная раздача файлов настраивается глобально для всего экземпляра сервера
[23:58:18] <OCTAGRAM> сайты разные, а у файлов коммунизм