Pull to refresh
-7
-0.2
Send message

Сейчас уже везде short 16 бит, int и long по 32 бита и появился 64-битный long long...

Утверждение не верное. в xNIX 64 битных изначально long 64 битный и это никто никогда уже менять не будет.

32 битные xNIX это исчезающе малый рудимент, а общая мировая тенденция идет к тотальной 64-х битности.

Адресуемого пространства в 64 бит хватит для всех мыслимых в обозримой перспективе задач (современные CPU и вовсе ограничены 48/52 реально используемыми битами для указателя, больше никому еще не потребовалось).

Единственное место, где еще живет 32 битный long - это win64, но с учетом дрейфа родной компании к Webkit/Edge, WSL/Linux и пр. - я думаю в ближайшие годы там тоже произойдет унификация (в новых SDK). Хотя скорее просто Windows везде заменят на Linux или Chrome OS или Mac OS каким.

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

P.S. И да, static_assert(sizeof(long)==8), static_assert(sizeof(int)==4) никто не отменял.

Назовите это условиями применения, да хоть EULA.txt , никто никому ничего не обязан же.

В конце концов, даже если в какой системе нет реализации mmap(), epoll() или clone(), и никто не озадачился написать нормальные API врапперы для них, то это проблема исключительно разработчиков и владельцев этой системы, которая "отличная от Linux". Пусть напишут, и проблема кроссплатформы отвалится сама собой.

Говорить что это технически невозможно - не надо. У Microsoft получилось почти весь linux syscall() набор привести к ядру NT в реализации WSL1, могут же, когда захотят.

A translation unit that uses any part of the standard library is not allowed 

И? Там написаны просто правила использования некоей стандартной библиотеки. Которая просто еще одна обычная библиотека, не сильно удачная, не самая эффективная, которую к слову никто и не заставляет использовать. Зачем вообще мне нужен этот ваш iostream, если есть stdio.h? (stdio.h тоже кстати можно не использовать, но пока не будем так круто ломать шаблоны).

А раз нам STL не нужна, то просто берем вот такой код.

#include <stdio.h>

#define enum enum class
#define long long long

enum Color {
  red, green, blue
};


int main() {
  long red = 12;

  Color my = Color::red;

  printf("%lld %d\n", red, my);

  return 0;
}

И задаемся вопросом - почему он скомпилируется - хоть clang, хоть g++, хоть чем.

И вообще, чуваки из комитета ISO, они кто? Продавцы и популяризаторы еще одной не сильно удобной библиотеки? А если я вообще не хочу ее использовать, то что теперь?

Лично мне слово std:: вообще ничего не говорит, это не часть языка, это просто еще одна библиотека, которую пытаются продавать вместе с языком как якобы неотъемлемую его часть (что не так), и не более того.

И потом следить за целостностью связи между ними?

Я там выше вроде говорил про это. Что данные для строк - это как правило или замапленный в память файл, или буфер обмена от сетевого I/O, или какой даже какой другой строковый буфер. И у этих всех источников там свой жизненный цикл, к отдельной строке ссылке на свой фрагмент имеющий перпендикулярное отношение.

Строка из пары указатель+размер это просто способ уйти от always-make-a-copy-with-trailing-zero к подходу zero-copy, когда никакие данные никуда не копируются, а строки (которые к примеру парсер понавыдает) просто ссылаются на исходные данные. Т.е. следить особо и не надо за целостностью, раз исходные данные не меняются.

Ну а если и надо следить, то в чем вопрос? Можно как угодно извратиться, да хоть счетчик ссылок донавернуть, RAII какой на ownership этого куска памяти, но ИМХО это ошибочный путь (хоть и используемый сейчас в 99.9% случаев). Не строками нужно мыслить, а более крупными понятиями, источниками и назначениями потока данных в целом, когда строки это лишь способ ссылаться на их фрагменты.

А вот про случай контатенации строк, т.е. строковый буфер (в т.ч. временный, на стеке) - это вообще отдельно.

Что за бред вы тут пишете. То есть, если я пишу класс работы с матрицами, мне вместо ясного и понятного Matrix4x4

Матрица 4 на 4? Это лабораторная работа 2 семестра наверное, а студентам не рассказали про BLAS/LAPACK и т.п.?

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

Теоретически (у меня самого такой реализации нет, но можно и запилить потом наверное), то если располагать сначала указатель, а потом длину, то можно сделать эдакое LEB кодирование size поля, исходя из Little Endian формата хранения числа. Т.е. если там до 127 байт длина, то size гарантированно однобайтовый, если менее 32767 - двубайтовый, ну и так далее. Т.е. не всегда иметь структуру из 16 байт, а иметь структуру переменной длины (9, 10, 12, ... , 16 байт).

В теории, если у тебя миллиарды строк - то это может дать некий выигрыш по памяти.

Но вообще там пост выше был больше стебовый, чем про реальные какие-то бенефиты от порядка расположения полей.

Ну или в LEB формате в чистом виде: https://en.wikipedia.org/wiki/LEB128

Как в вашем случае в такой ситуации определить длину строки?

Вопрос не понятен. В моем примере выше строка описывается просто двумя 64х битными числами - указатель и длина, соответственно.

И от того, как располагать - ptr*, size или site, ptr* мало что меняется, это и так и так 16 байтовая структура.

Ну и что не так с "практически всегда"? Практически всегда - это и есть практически всегда и везде, за исключением тех областей, где тебе лично никогда в своей жизни работать и не придется.

Микроконтроллеры и wifi раутеры, к примеру. IBM мейнфреймы и прочие i-series. Зачем пытаться постоянно учитывать многообразие этого безумного мира, если твой код и так никогда туда и не попадет? 0.5% потенциальных пользователей твоей библиотеки с 32-х или 31 битностью указателя? 0.005% потенциальных пользователей c OpenBSD?

Зачем они?

Дефайнить ключевые слова запрещено - не скомпилируется. 

Дефайнить можно что угодно - все скомпилируется. Незнание матчасти не простительно.

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

Кек кринж. word от short отличается знаковостью и т.д. Слабоумие?

Зачем нормальным ЛЮДЯМ иметь в голове мапу слова на число и постоянно заниматься приседаниями что бы понимать что больше и что меньше и во сколько раз? 

Ну зачем мне видеть на КАЖДОЙ странице кода 10-15 напоминаний о том, что в int именно 32 бита, не 31, не 33, а именно 32? Чтобы что? На кой мне вообще постоянно помнить, сколько там бит? В знаковом целом?

Сразу видно, что вы дальше своей платформы ничего не знаете и крос платформ для вас это ругательства.

И в какой такой современной платформе int это не 32 битное целое? И да, даже Windows поддержка это уже ругательство, она как минимум не проходимо не POSIX, никакими MSYS или WSL ее не исправить, остется только выбросить, и что теперь? Тратить время на поддержку любой ценой?

Что написать в коде что бы не усложнять себе жизнь макросами и гарантировано иметь 64 бита везде?

А где сейчас не 64 бита? Мобилки все 64 битные, десктоп 64 битный, серверы 64 битные.

Микроконтроллеры и wifi раутеры?

А вообще забавно конечно. Никогда не думал что даже в таком вопросе, как int vs i32 у стольких рванет тяга к обминусовыванию.

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

Даже повод задуматься о причинах такого странного явления. Наверное.

Какой критерий нормальности? Привычность анониму из интернета?

Очень простой - общепринятость. Vast majority. Если у всех по два уха и один нос, а у кого-то ушей четыре и три носа - то он точно не нормальный.

Прямо даже интересно стало, сколько языков, у которых в спеке написано, что sizeof(int) равен 4? 

Давай проще, у кого написано, что он не 4?

PDP-11, MS-DOS, Win16 у кого еще? Ну ок, википедия говорит была какая-то Classic UNICOS, у нее int был на 64 бита. И только из-за MS-DOS и UNICOS мы должны все думать, что бывает в мире не 32-битный int? Серьезно?

типы int32_t и остальные этого семейства, то будет почти так же хорошо, как в Расте.

Я уже написал выше, почему цифры в коде это крайне плохо. И в С++ и в Rust с этим очень и очень плохо, но в C++ не так безнадежно, std::int32_t есть конечно любители, но в массе люди просто живут с int

А вот с long конечно сложнее. Из актуальных платформ только Win64 его считает всегда 32-битным, что клинический случай конечно.

Под xNIX уже сегодня можно просто писать long, он практически всегда 64 битный. 32 битные архитектуры практически вымерли, за исключением контроллеров, но там пишут на С, не на С++.

А писать long long - это и просто некрасиво, и просто нелепо. Как и int64_t

В конце концов в проекте можно сделать static_assert(sizeof(long)==64) и на этом и закончить.

А страдальцам из ILP32 мира просто прописать #define long long long

Затем, что Rust - это не тот же самый язык, что и Си, 

Хорошо, для непонимающих иронию поясню отдельно.

Для нормального программиста видеть в коде любые числа и цифры, отличные от нуля - это ну прям кринж кринжовый. Потому как это цифровое все должно быть вынесено в заголовки, и немедленно заменено символьными именами констант. INT_MAX, N, M и вот это вот все, во всех букварях же про это пишут в первых главах.

Открываем любой код на Rust - и он прям густо густо обвешан ну очень ценными цифрами 8, 32, 64, которые:

а) никакой полезной и нужной информации (как цифры) на самом деле не несут

б) рябят и раздражают, потому что цифры в коде и должны раздражать настолько, чтоб немедленно их заменять на N, M и прочие DEFAULT_POOL_SIZE

Догадаться, что выжить может и должен только LP64 (а все остальное должно отмереть как и BigEndian какой вместе c VAXами), не, мы не такие, а мы лучше свой новый еще один "стандарт" именования запилим, в дополнение к чудным int32, int32_t, __int32, _int32, ____int32, __int32_t, std::int32_t, POCO::Int32, __INT32_TYPE__, int_fast32_t, int_least32_t, signed, int_t, __int32t, __Int32T, Int32T, INT32, i32_t, int32

Ну мы же тоже любим все называть не как у всех. Если чувакам на C/С++ так весело упарываться с алиасами к int можно, то а мы чем хуже, да? Как же вы все без i32 жили до этого, получите распишитесь.

Ну молодцы, таки решили проблему раз и навсегда.

Т.е для сравнения два адреса разбиваются на наборы элементов и сравнивается содержимое этих наборов.

Прикиньте количество комбинаций для сравнения :-)

Возможно не совсем понял задачу, но мне кажется там нужно просто привести адреса к некоей нормальной форме (Субъект|Район|Нас. пункт|Улица|дом-строение|квартира-кабинет|) и потом просто отсортировать и так и обрабатывать потом потоком. Дефективные данные можно вычислить по непопаданию в КЛАДР (хотя это еще тот эталон) и отдельно нечетким поиском. Да даже просто по кластеризации от имени улицы-проспекта-переулка можно уже сильно сократить поиск.

Естественно, что обработчики между собой не общаются никак - им это не нужно.

Ну вот, треды не нужны, синхронизация не нужна. Исходный блоб с данными лежит на диске, мапим его через mmap() в разных процессах и жуем себе данные каждый рабочий независимо друг от друга.

Но 50млн - это вроде совсем не много, базы данных такое пережевывают за секунды (минуты, если какие регексы туда в SQL запускать).

Простите, но как вам там живётся в 2004?

В 2004м жилось замечательно, свежие девки (и это не только DevExpress), Delphi, IE6/Maxthon, Windows XP SP2, RHEL 3, Oracle 9iR2, Rock solid stuffs everywhere

Потоки сегодня нужны, ну, для параллельной обработки, когда у вас легко может быть сотня ядер.

Опять 25. Я говорю что потоки не нужны, т.к. в линапсе они сейчас почти ничем не отличаются от процессов. Зато потоки в отличие от процессов не имеют защиты по памяти (куча и стек как минимум).

Единственное значимое отличие - что gdb/lldb сильно туго умеют отлаживать сразу много процессов, это да, напрягает. Но это можно пережить, если для отладчика пересобирать проект в режиме - "ну ок, а вот теперь все наши дочерние процессы становятся тредами". Но и это нужно редко, только если интенсивный межпроцессный пинг-понг отлаживать.

Я больше говорил что pthreads давно пора выкинуть на помойку, вместе с System V IPCs. А все делать строго в один поток на одном единственном ядре единственного CPU - я такого нигде не говорил.

И даже в линупс его завезли примерно к 2010. Лет 5 назад там так вообще нормально сделали.

А epoll() и 10к начали активно форсировать емнип только в 2009-2012м, довели до ума сильно позже, считай что позавчера.

А libaio ужасы - там я уже не помню, но кажется в Userland создавались пулы потоков, которые вокруг blocking I/O крутились, в общем костыль какой-то был сильно странный для Oracle, больше его никто и не использовал.

Это все сильно древние и темные времена и уже давно бесполезные знания, вроде навыков в FreeBSD. Осталось только про himem.sys чего вспомнить :)

работать с которыми и быстрее и проще.

Интересный код конечно выше. Строки в 64к это ок, но так мало кто уже извращается.

Вообще в когорте правильных парней больше принята пара { *ptr, size_t size }, где лишние нолики в хвосте можно и отбросить или да, и вовсе всегда привести к { *ptr, int(short) size}

https://github.com/fredrikwidlund/libreactor/blob/master/src/reactor/data.h

https://faxpp.sourceforge.net/structFAXPP__Text.html

https://github.com/google/gumbo-parser/blob/master/src/gumbo.h#L88

Это кстати можно и как критерий выбора грамотных фундаментальных библиотек представить.

Если автор библиотеки на старте догадался заменить ASCIIZ строки на нормальные пары указатель+размер, то у него уже явно просветвленное zero-copy сознание в голове (а не мешанина из какой унаследованной и/или бездумно зазубренной из букварей благостной ASCIIZ чуши), и с ним можно иметь дело. Жаль только что их очень мало таких.

А вот чудаки из C++ комитета как всегда отожгли напалмом и сделали через .... в общем все как всегда обычно:

https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/string_view#L583

И это лишь одна из причин, по которой с ними дела иметь не хочется от слова вообще, уж сильно у них большой мозг.

Вот еще один, который не очень умеет в безопасный и надежный код:

https://github.com/LMDB/lmdb/blob/mdb.master/libraries/liblmdb/lmdb.h#L286

и надо отдать должное, производный и доведенный до ума проект LMDB -> MDBX исправил и представление строки сразу

https://github.com/erthink/libmdbx/blob/master/mdbx.h#L752

Забавно, забавно. Никогда и не задумывался до этого, что даже по такому признаку, как пишут - {data, size} или {size, data} можно сразу отделять тех, с кому тебе скорее всего точно не по пути.

Можно сказать дискуссии прошли не зря, потраченное время уже окупилось.

Это ведь не int стали называть i32, а тридцатидвухбитное целое со знаком стали называть i32, что совершенно логично и не должно по идее вызывать вопросов.

Ок, задам вопрос проще. Почему во всех нормальных языках 32 битное знаковое целое уже много лет как называется просто int, и для чего в Rust его внезапно назвали иначе?

Что бы что случилось? Чтобы безопасность повысилась?

А если погуглить хоть немного?

И узнать, что все озвученные выше задачи давно решены базовыми системными С библиотеками. Зачем это переписывать на Rust заново? А...наверное безопасная безопасность повысится, да?

Да они и в clang и в msvc тоже есть, __declspec(property) через ms-extensions. Работают кстати очень хорошо, хотя разрдражает видеть в auto-complete для VS Code и свойства и get/set функции одновременно (их заставляют public делать).

Ну и GCC гордый весь такой и их не приемлет.

Вот только это нестандартные расширения, а да заголовочная декларация пропертей в этом расширенно-нестандартном C++ не менее уродлива, чем весь Windows.h.

Можно конечно привыкнуть, но глазам все равно больно, даже если через макросы окультурить.

При этом приходится следить за состояние конвейера чтобы он не переполнялся т.к. скорость раздачи всегда выше скорости обработки и разбора. Увеличивать количество обработчиков тоже бесконечно нельзя т.к. это далеко не единственная задача системы и есть ограничения по количество процессорных ресурсов на нее выделяемых. Т.е. всегда балансируем между временем выполнения и общей загрузкой системы.

Подобные задачи даже на bash с его &, wait, sleep, +check $(jobs | wc -l) вполне себе успешно решаются. Треды то там зачем?

Можно пример задачи (область), где обработчикам нужно друг с другом общаться?

а про то, что утверждение "потоки используют только люди с низким уровнем квалификации и везде надо переходить на модель с fork/clone" мягко говоря спорное.

Никакого тут спора нет. Там вверху было обозначено - потоки обычно нужно просто заменять на асинхронный I/O (epool и т.п.), т.к. в большинстве случаев эти ваши треды просто используются для обхода ограничений этого вашего blocking I/O, а это и есть признак низкой квалификации. Хотя почти все так до сих пор и делают.

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

А так чтоб прям кучу CPU нагрузить реальной нагрузкой - это еще надо задачи такие найти. Я лет 15 назад в бытность очень сильно удивился, когда даже на задаче обработки-перекодирования потокового видео со спутника замена многотредовой модели на асинхронное I/O дала прирост в 10 раз, нагрузка на CPU упала с 90% до 8-9%, и позволило подключить в 5 раз больше карт на каждый сервер, больше туда просто уже не влазило физически.

Потом и выяснилось, что pthreads и примитивы синхронизации в ядре - это еще та халтура наколеночная. Может для какого httpd apache с его 5 реквестами в секунду это и ок, но в целом... впрочем, в целом обычно и так все понятно, что треды - это не про перфоманс, а просто "хочется для резюме и опыта попробовать".

о что мешает хакеру вызвать из дочернего процесса mprotect на все созданные mmap c MAP_SHARED и прочитать/записать все что нужно?

Мы защитное программирование делали не сколько от хакеров, сколько от дятлов и багов (кстати помогает, судя по логам). А так - что-то мне подсказывает, что mprotect это по сути указатель на куда-то там, и этот указатель можно попробовать ловко скрыть, натолкать туда редирект какой, а реальный вызов mptotect() делать как-то отдельно, по команде от монитора процессов...

Но это уже пошел хакинг, интересный конечно, как таска для воскресного бэклога. И за наводку в pkeys спасибо, хотя выглядит это пока не сильно вдохновляюще (не всякий x64 сможет): https://www.kernel.org/doc/html/next/core-api/protection-keys.html

Но идея конечно зачетная. Треды друг от друга позабарикадировать. Мы треды применяем для Development/DEBUG режима, потому как обычно отлаживать в VSCode/LLDB кучу дочерних процессов вообще никакого удовольствия нет, надо c pid этими возиться и тормозит оно в отладчике прилично...

А так и повод железки обновить...

Ну есть pkey_mprotect для того же самого в мнопоточной среде, если оно нужно. Даже прямо в документации пишут:

И что что есть? Как это может помочь с fail fast / SIGSEGV ?

Ну вот прилетел хакер-дятел в вебсессию, почитал что ему не положено. И весь процесс кирдык и навернулся в корку, вместе с другими сессиями и веселыми тредами, кому легче стало?

А если у меня живут отдельные процессы воркеры для пережевывания реквестов - то отмирание отдельного процесса-обработчика пользовательского запроса лишь побеспокоит тоже отдельный процесс сервис монитор, чтоб он зареспавнил в пуле этого временно выбывшего из строя воркера. Хакер-клиент же спокойно получит свою 500-ую, остальные даже не заметят локальной катастрофы.

Это у вас уже какая-то сверхидея собственной исключительности.

Боже упаси. Это все давно известные и вовсе не мои идеи. Я единственно просто не могу найти их собранные в одном нормальном бэкэнд фреймворке, только в разбросанные частях в разных имплементациях разных людей, еще и на разных языках. А вот чтоб целостно - увы такого ни у кого нет, и это удручает, т.к. заниматься продуктизацией и популяризацией очередного userver или какого еще одного тарантула не сильно и перспективно, даже нелепо.

Information

Rating
Does not participate
Registered
Activity