Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1.
И очень зря. Не должен один процесс жрать больше 2 ГБ. А для 64-битных систем следует разбивать приложения на несколько процессов/библиотек.
ЕМ>или действительно есть серьезная необходимость изначально задавать эти адреса/размеры глобальными константами
Для стандартизации и хоть какого-то ограничения аппетитов быдлокодеров. Сейчас почти все ограничения сняли, и макаки пишут десктопные приложения на электроне. А страдают обычные юзеры, у которых через 5 лет "морально устаревает" самый топовый ПК. Раньше для ZX Spectrum с 48 КБ памяти и 8-битным процессором 3.5 МГц писали 3D шутеры и стратегии реального времени.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[3]: Откуда такая неизбывная приверженность к константам?
Вот у меня ноутбук на ALT Linux с 16 гигами ОЗУ. Появляется сообщение о нехватке памяти, если одновременно запущены Telegram, Postgres, Kafka в Докере, браузер Chromium с несколькими вкладками и Java приложение в IDEA (т.е. стандартное рабочее окружение). И затем обязательно что-то падает, обычно это браузер. Огромное спасибо тем, кто решил, что одному процессу нормально жрать несколько гигов, а у блогов и форумов вроде Хабры должны быть такие же системные требования как у Фотошопа. Впрочем, JavaScript это в целом раковая опухоль интернета...
«Закон Вирта» — шуточное высказывание Никлауса Вирта (1995) в духе законов Паркинсона: «программы становятся медленнее куда шустрее, чем компьютеры становятся быстрее»[1][2], используемое для демонстрации нарастающих проблем с производительностью программного обеспечения, несмотря на прогресс аппаратного.
Мннение Андрея Столярова, бывшего преподавателя МГУ, автора лучших русскоязычных учебников по программированию:
Только сначала надо всех вебщиков перестрелять к чёртовой бабушке, поскольку браузеры и "современный" веб на таких машинах не работают. Остальное работает нормально, у меня до сих пор eeepc901 в эксплуатации.
У Гугла есть свои вполне определённые цели, и чтобы их достичь, нужно кроме всего прочего заставить весь мир то и дело "обновлять" браузеры. В 2010 году я прекрасно пользовался браузерами 8-10-летней (на тот момент) давности, и всё работало; сейчас в инете постоянно попадаются сайты, не желающие работать с браузером, которому меньше года, и один из основных таких -- поганый ютЪюбик. А ещё Гуглу очень нужно сделать так, чтобы браузеров было как можно меньше — выкинуть с рынка всех независимых разработчиков, и перманентное повышение сложности протоколов и форматов явно делается специально для этого.
Несомненно, https тут лишь один из многих инструментов, что не исключает.
Редко сейчас вижу (особенно среди программистов) тех, кто способен думать, а не радоваться всему подряд. Сколько визгу было на тему новых версий флэша, JS`а, HTML5, WebAssembly, Java, Python и т.п. Только со временем приходит осознание, того что вреда от всего этого больше, чем пользы. Причем осознается это обычно в тот момент, когда покупаешь новый компьютер и понимаешь, что "быстрее" не стало. Все ушло на компенсацию большей прожорливости тех же самых программ.
Я недавно проводил эксперимент. Я работал за P4 с 512 МБайт ОЗУ и Slackware (тогда еще 14.2). На этом железе работало все, что мне надо. Все, кроме "современного" браузера. Поэтому как минимум я не один, кто ощущает регресс в сфере софтовыдреста современных "программистов".
Для тех серверов, где необходимо полностью загружать в память БД, должны использоваться специальные аппаратные архитектуры. Не те, что стоят на массовых персональных компьютерах у обычных пользователей. Раньше были мейнфреймы, например.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Сперва были и 640 кб доступной обычной памяти, и жестко заданные адреса областей внешних устройств, хотя все это можно было запихать в BIOS, и возвращать конкретные адреса по запросам. Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1. В 64-разрядной винде снова 8+8 Тб. Сейчас читаю про макось — и там тоже сплошные явно определенные константы.
Я тут книжку читаю, про AS/400. Вот там сделано правильно.
Почему в других частях IT это иначе? Потому что:
1) Там нет умных людей
2) Там нет человека с железной палкой
3) Там умным людям железную палку не дают
4) Там умные люди железную палку брать не желают
Re[18]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Sharowarsheg, Вы писали: S>Не помню, чтобы что-то куда-то не помещалось. MultiEdit с дос навигатором помещались везде.
Да ну? Помню, послушал в универе нескольких сокурсников, насколько-де крут DOS Navigator, поставил — через пол-дня снёс нафиг из-за его аппетитов по conventional memory, приходилось выходить в голый DOS, запускать что тебе нужно, далее возвращаться в "навигатор", иначе Not enough memory или недостаточно файловых хэндлов.
пояснение
когда-то давно-двано был файлик config.sys с разными параметрами, кто не застал, рекомендую почитать как ваши деды выживали (ц).
P.S. Хотя с точки зрения оболочки — да, прям много фишек напихано было по сравнению с Нортоном. Было б доступно пару мегов вместо 640К для conventional memory — ценнейшая была бы вещица.
Re: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Сперва были и 640 кб доступной обычной памяти, и жестко заданные адреса областей внешних устройств, хотя все это можно было запихать в BIOS, и возвращать конкретные адреса по запросам. Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1. В 64-разрядной винде снова 8+8 Тб.
Это что ещё за 8+8 такое, просто любопытно? А причина может быть простая — одним битом удобно управлять трафиком на системной шине: нет бита == RAM, есть бит == MMIO, и это, например, прибито гвоздями в железе.
Re[17]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
S>>В программах дофига констант, от которых требуется, чтобы они просто не были слишком плохи.
ЕМ>Ну вот конкретно в Ваших программах, какими константами задаются адрес и максимальный размер кучи, адреса загрузки системных DLL и т.п.?
Конкретно в моих адреса загрузки системных DLL не задаются, я же не пишу загрузчик системных DLL. Размеры массивов (битность индексов) — задаются константами 16, 21, 24, и 48 (в разных местах и применительно к разным сущностям, естественно).
S>>Для DOS было достаточно 640 KB, а когда перестало быть достаточно, перестала существовать DOS, вместе с x86 реальным режимом.
ЕМ>Это Вы уже все прочно забыли. HiMem/Emm386 появились в самом начале 90-х, и не от хорошей жизни. Иногда только эти 100-200 дополнительных килобайт и позволяли запустить софт, который иначе никак в память не помещался.
Не помню, чтобы что-то куда-то не помещалось. MultiEdit с дос навигатором помещались везде. Первое, что перестало помещаться, был DOOM, для которого сделали DOS4GW.
S>>Так и для 32 бит достаточно, легко, и удобно сделать разделение 2:2
ЕМ>А зачем именно 2:2, а не m:n?
Чтобы по старшему биту можно было узнать, это пользовательский указатель, или ядерный.
S>>Старый софт, который уже не переписывается, всё ещё можно запустить, даже на физической машине, если нужно, но когда перестало быть достаточно 2 GB на процесс для нового софта, выкинули x86 вместе с 32-битным режимом, и всё новое, что могло бы сожрать больше 2 GB, написали на x64.
ЕМ>И это тоже наблюдения из мира розовых пони. Майкрософту бы нафиг не сдалось переделывать 2:2 в 3:1, если бы не массовое давление со стороны юзеров винды, в том числе жирных корпораций.
У микрософта в то время было достаточно денег, чтобы купить все те "жирные" корпорации, а также купить пользователей и в рабство обратить. Это собственные микрософтовские программисты, которых тоже перфекционизм одолел, захотели сделать все константы настраиваемыми, и обосрали всю малину — и, конечно, вызвали тыщщи синих экранов.
S>>На ближайшие десять лет x64 достаточно, и константа 8:8 TB или сколько там, вполне прекрасна.
ЕМ>Ну да, один французский король тоже нечто подобное говаривал.
S>>Кончилось поколение — кончилась константа, бери другую.
ЕМ>Хорошо, что математики, несколько сотен лет назад придумавшие заменять конкретные числа буквами, так не думали.
Математики не в состоянии сделать ничего практического. Например, нельзя построить мост из одних букв, какая бы ни была математика. В какой-то момент придётся подставить вместо букв хотя бы длину и ширину цифрами.
Здравствуйте, Worminator X, Вы писали:
ЕМ>>Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1. WX>И очень зря. Не должен один процесс жрать больше 2 ГБ.
К этому времени уже было совершенно нормально иметь, например, файл базы данных на 50GB.
И хотеть этот файл замапить в память для прямого доступа.
Ограничение в 2GB этому мешало.
С другой стороны, костыль в виде 3+1 откровенно усложнял код и тормозил исполнение, поэтому переход на 64 бита надо было делать как только приблизились к этой границе.
The God is real, unless declared integer.
Re[2]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Worminator X, Вы писали:
WX>Не должен один процесс жрать больше 2 ГБ.
Это все крайности: для одних — "сколько дадут, столько и сожрем", для других — "нельзя жрать больше N".
Жрать нужно столько, сколько объективно требует задача, с разумным (10-20-30%) допуском на неоптимальность. Для локальных, временных задач вполне допустимо хоть стократное превышение по ресурсам, если оно не выходит за четкие пространственно-временные рамки ("надо срочно сделать по базе отчет нового формата, плевать на оптимизацию, главное — быстро"). Беда в том, что такой подход нынче совершенно нормально применяется в массовом продакшене.
WX>А для 64-битных систем следует разбивать приложения на несколько процессов/библиотек.
Если суть задачи предполагает такое разбиение, то почему не делать этого для любых систем? А если достаточно компактный код занимается вычислениями, для которых потребны десятки гигабайт, то какой смысл его разбивать искусственно?
WX>Для стандартизации и хоть какого-то ограничения аппетитов быдлокодеров.
Для этого как раз лучше всего иметь в системе запросы "каков максимальный объем адресного пространства?", "сколько сейчас доступно памяти?", и вводить в обиход системы, где эти значения могут быть достаточно малыми. Тогда быдлокодерам придется хоть как-то соотносить свои аппетиты с тем, что может встретиться в реальности. А когда в реальности не существует 32-разрядных систем с пользовательским АП меньше 2 Гб, то аппетиты закладываются именно на это.
WX>Сейчас почти все ограничения сняли, и макаки пишут десктопные приложения на электроне. А страдают обычные юзеры, у которых через 5 лет "морально устаревает" самый топовый ПК.
Ну так и я о том же. Гарантированные большие цифры этому косвенно способствуют.
Re[3]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Я плохо представляю себе процессор (особенно в то время) с неограниченными размерами адресных регистров и количеством проводов на внешней шине. ЕМ>Пока смена архитектуры влекла за собой смену программной модели, и программы с 8-разрядных ПК не переносились автоматически на 16-разрядные, а с 16-разрядных — на 32-разрядные, разумно было исходить из разрядности архитектуры.
Где это у нас автоматический перенос программ?
К нему только-только подходят (ну если не считать Ada, Erlang и Python, и то, как только подходим к задачам типа математики или нейросетей — всё, приехали).
N>>А если мы имеем 20 бит, то потеря примерно половины из них на разные ROM, I/O и прочее — вполне естественна. ЕМ>Господь с Вами, где там естественность? Половина от мегабайта — 512 кб, а на "разные ROM, I/O и прочее" попервости уходило чуть больше сотни.
A0000-BFFFF видеопамять всех видов
C0000-DFFFF область расширителей
E0000-FFFFF BIOS (да, занимал сильно больше 64KB, начиная ещё с AT)
Ну да, с запасом. В 1 из 3 (расширители) этот запас оказался лишним. В 2 из 3 (видеопамять и BIOS) стало не хватать, первое достаточно быстро поднялось до 256-512KB и ушло в отдельные адреса, второе — чуть медленнее, но микрухи ещё до EFI ставили вплоть до 512KB.
Конечно, если бы их поменяли местами, можно было бы непрерывным куском откусить от области расширителей, а не мапить в неё отдельным неудобным куском, как делали с XMS. Но и так разница между 640KB и 768KB не так долго была критичной.
И не надо вспоминать про "хватит всем", этот миф давно развенчан.
N>>то, что BIOS запускался с опять же константного адреса F000:FFF0, ты уже не считаешь? Что IDT реального режима сидела по адресу 0:0? ЕМ>Это все жалкие копейки, какой смысл их вообще упоминать? Коню понятно, что ряд основных параметров неизбежно приходится фиксировать. Но этих параметров очень немного, подавляющее большинство остальных выбирается произвольно.
Вот я и пытаюсь понять, где у тебя граница между "ряд основных" и "подавляющее большинство остальных".
N>>Я не вижу твёрдых причин делать эти параметры переменными и требовать извлекать из какого-то справочника, если нет нескольких таких устройств (ресурсов, в общем случае). Там, где было (как компорты, в количестве от 1 до 8), BIOS таки давал такие данные по запросу. ЕМ>То есть, протокол PnP Вы считаете стратегической ошибкой, и адреса/порты/прерывания до сих пор следовало настраивать перемычками?
А это уже от тебя встречный поиск границ
Нет, не считаю. Потому, что комплект аппаратуры стал вариабельнее. И по количеству (кто мешал впихнуть 4 ATA контроллера?), и по типу (вот у этой машины вообще нету ни ATA ни видео, зато есть два SCSI, один медный FiberChannel и COM-мультипортовка на 64 порта). И когда стало _легко_ делать вариабельные адреса, то это стали делать.
Заметь, MCA, на которой это впервые появилось, это ~1987. PCI это 1991. Прогресс был стремительным за это время, и возможность перешла из дорогого сегмента в общий. Но и то — вначале PCI имел подпорки для AGP, для ATA и ещё для чего-то, отдельными требованиями в стандарте. А это такая же фиксация.
Но и при этом полно зафиксированных вещей. Если ты посмотришь на описания северного моста, то у него на корневой PCI шине дофига фиксированных устройств, которые настраиваются через конфигурационное пространство PCI. Это сам корневой мост, это контроллер памяти, это ещё много чего. С приходом северного моста внутрь процессора суть не поменялась, там те же настройки, и BIOS начинает работу с их кручения. И там много ограничений в духе "Core 4-го поколения имеет только 40 (навскидку) физических линий адреса памяти", а в следующем поколении вдруг добавляют ещё 2 линии. Это всё естественные процессы развития.
N>>Всегда есть какие-то постоянные параметры. Начиная с кодов команд процессора ЕМ>Боюсь, Вы не поняли исходной идеи. Или поняли, но из природного упрямства решили довести ее до абсурда.
Повторяю: не из какого-то упрямства, а в порядке поиска границ. Ты сам допускаешь, что какие-то значения должны быть константными. Но чётких критериев разграничения не дал.
EM>>>в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1. N>>Эта переделка вообще потребовалась, потому что на 64 бита не успели быстро перейти. ЕМ>А если бы изначально, вместо фиксации 2+2, определили M+N, то переделки не потребовалось бы вовсе, а реализация запроса M и N была бы, наверное, в тысячи раз дешевле той переделки.
Какие нафиг N и какие M? Чему они могли бы быть равны?
Есть определённые правила оптимальности конфигурации, за пределами которых она становится перекошенной и оттого бесполезной. Не было причины делать память юзерленда менее 2GB, потому что не нужно ядру столько; и невозможно давать на толстой машине (2-4GB RAM) меньше 0.5GB ядру, потому что оно тогда только и делало бы, что гоняло байтики между буферами. В линуксе тех времён было такое понятие, как bounce buffers. Почитай про него.
Вот потому и делали 2:2, 3:1 и для особых извращенцев — 3.5:0.5, но в последнем случае уже гнали калёной метлой на 64-битные машины, на которых не надо было упираться в ограничения и работали они уже лучше, чем в таком кривом варианте.
N>>В остальном от неё проблем больше, чем пользы. ЕМ>Как практически от любого костыля, призванного исправить последствия грубой непродуманности.
Ну расскажи, в чём именно непродуманность.
N>>то, что в автомобиле конкретные габариты и диаметр колёс, ты тоже будешь считать неоправданно зафиксированной константой? ЕМ>Если Вы о габаритах кузова, то они соответствуют как раз исходным константам архитектуры — разрядности магистрали и адресного пространства.
Нѣтъ! Им соответствует функциональность типа "возить до 4 человек весом до 100 кг с грузом в объёме до двух обычных чемоданов, со скоростью до 150 км/ч". А какого размера будет при этом машина — это уже как раз вопрос реализации.
EM> Неоправданной фиксацией было бы, например, искусственное, произвольное разделение багажника на секции, из-за которого невозможно было бы загрузить предмет, не помещающийся в секцию.
Чудесно. У меня что в старой, что в новой машине такое разделение есть. Под основным дном багажника место для запасного колеса. И да, я туда рядом с колесом закидываю всякие мелочи типа ключей, но не смог впихнуть электронасос для колёс. И я вполне могу сказать, что это разделение произвольно. Но я и производителей вполне понимаю, для типового применения всё сделано правильно.
N>>А питающее напряжение в электросети? ЕМ>Это тоже исходный параметр. Неоправданной фиксацией константы было бы, например, произвольное ограничение величины тока, потребляемого из одной розетки.
Ну так и оно тоже есть. Большинство наших розеток ограничены 10A. А если я хочу 10.8? Ставить другие розетки и вилки.
Вернёмся от аналогий к основному вопросу. Я всё-таки не вижу, где эти ограничения были бы настолько неоправданны, что заставили бы страдать индустрию без причины на длительный срок. Вместо этого я вижу, что как только упирались в них, достаточно быстро находился вариант решить проблему переходом за следующий порог, который при этом был в разы дальше. Но чтобы без порога вообще — такого не бывало, потому что мы в реальном мире.
The God is real, unless declared integer.
Re[2]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Слава, Вы писали:
С>Я тут книжку читаю, про AS/400. Вот там сделано правильно.
По AS/400 вроде бы существует только одна описательная книжка от Френка Солтиса и она на 99% состоит из технической рекламы. И там не сказано, что, в современных терминах, это одна JVM/.NET виртуальная машина, растянутая на всю физическую машину (или виртуалку) с контролем доступа между юзерами, собственным языком исполнения, похожим на байткоды JVM и .NET с точностью до переименования команд (и теми же методами исполнения — AOT и JIT), реляционной базой данных вместо файловой системы (для особо некоторых можно подключить и FS), и посоленной сверху терминологией IBM везде вместо средне-привычной по индустрии. Фактически, её описание, для современных ITшников, можно было бы свести к полстраницы вместо тех двести или сколько там спама в этой книге.
Можно, конечно, сказать, что это всё "правильно" по сравнению с голым железом и его ограничениями, но работает-то она поверх того же голого железа (POWER разных поколений). Ну понятно, что в JVM, если ты не лезешь в unsafe, пофиг, сколько битности в указателе. Но уже целочисленные типы данных имеют те же ограничения, что и везде.
С>Почему в других частях IT это иначе? Потому что:
С>1) Там нет умных людей С>2) Там нет человека с железной палкой С>3) Там умным людям железную палку не дают С>4) Там умные люди железную палку брать не желают
"В других частях IT" в первую очередь была жесточайшая конкуренция за ресурсы и даже пара процентов имела значение. И когда наконец сложились условия, чтобы Java выстрелила, это случилось, и она сделала то же самое по сути что та же AS/400, только поверх более привычной среды. Автоматическое управление памятью — на месте и в полный рост. Хочешь всё делать через БД? Пожалуйста, тебе все интерфейсы, только без загоняния той же "железной палкой" в прокрустово ложе. Миллионы энтерпрайз-программистов ничего больше не знают и счастливы. Что ещё нужно?
А IBM умела в те времена (и в какой-то мере умеет и сейчас) заставить купить даже заведомо неэффективное на порядки (как было с AS/400 вплоть до ~2000 года) по принципу "никого не увольняют за покупку от IBM". Хакер с портфелем и круглой печатью сильнее хакера с клавиатурой.
Здравствуйте, Worminator X, Вы писали:
WX>Вот у меня ноутбук на ALT Linux с 16 гигами ОЗУ. Появляется сообщение о нехватке памяти, если одновременно запущены Telegram, Postgres, Kafka в Докере, браузер Chromium с несколькими вкладками и Java приложение в IDEA
Я правильно угадал, что больше всего жрет браузер? У себя я еще не видел более жручего приложения (в игры не играю, фото/видео не монтирую).
WX>Огромное спасибо тем, кто решил, что одному процессу нормально жрать несколько гигов
Я не пробовал Chromium, но Chrome и Firefox уже давно создают процессы десятками. Ну ограничите Вы память на один процесс — они запустят их втрое-впятеро, и в итоге сожрут еще больше, ибо накладные расходы вырастут.
WX>у блогов и форумов вроде Хабры должны быть такие же системные требования как у Фотошопа. Впрочем, JavaScript это в целом раковая опухоль интернета...
Это полностью поддерживаю.
WX>Мннение Андрея Столярова
Столярова нужно воспринимать очень осторожно и взвешенно. Он грамотный мужик, у него много разумных высказываний, но на каждое разумное он приводит по нескольку таких, что уши вянут. Ему вообще плохо даются компромиссы, он больше сторонник крайностей.
WX>Для тех серверов, где необходимо полностью загружать в память БД, должны использоваться специальные аппаратные архитектуры. Не те, что стоят на массовых персональных компьютерах у обычных пользователей. Раньше были мейнфреймы, например.
Что в тех мейнфреймах было "специально аппаратного" для поддержки полной загрузки БД в память, чего нет хотя бы в i486?
Re[7]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Никто такой памяти не ставил до середины 80-х, и то только самые толстые.
ЕМ>Я у Чена наткнулся на описание реального косяка с Win 95, которая отказывалась грузиться, если памяти было больше 480 Мб. То, что для "первичной кучи" отводился блок фиксированного размера, это еще ладно, но то, что наличие памяти, описание которой не влезало в этот блок, приводило к отказу в загрузке — это уже за пределами разумного. Это, блин, уровень студента-второкурсника.
Remember, Windows 95’s target machine was a 4MB 386SX and a powerful machine had 16MB.
...
One of my friends got 96MB of memory on his machine to test that we didn’t tank under “insanely huge memory configurations” and we all drooled.
Откуда такая неизбывная приверженность к константам?
Сперва были и 640 кб доступной обычной памяти, и жестко заданные адреса областей внешних устройств, хотя все это можно было запихать в BIOS, и возвращать конкретные адреса по запросам. Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1. В 64-разрядной винде снова 8+8 Тб. Сейчас читаю про макось — и там тоже сплошные явно определенные константы.
Это что-то вроде профессионального бега по граблям, или действительно есть серьезная необходимость изначально задавать эти адреса/размеры глобальными константами вместо того, чтобы определить их только внутри ядра, а всем внешним модулям (даже драйверам и системным службам) возвращать конкретные значения исключительно по запросам)?
Здравствуйте, aik, Вы писали:
aik>Это что ещё за 8+8 такое
Ошибся — 8 Гб там только на процессы, адреса ядра размазаны с 0xFFFF0800'00000000 по 0xFFFFFFFF'FFFFFFFF. Но все равно ж это явно определенные константы — какая необходимость жестко фиксировать их наперед?
aik>А причина может быть простая — одним битом удобно управлять трафиком на системной шине: нет бита == RAM, есть бит == MMIO, и это, например, прибито гвоздями в железе.
В каких-нибудь микроконтроллерах это может быть и удобным, но не в вычислительных же (в широком смысле) системах.
Re[3]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Ошибся — 8 Гб там только на процессы, адреса ядра размазаны с 0xFFFF0800'00000000 по 0xFFFFFFFF'FFFFFFFF. Но все равно ж это явно определенные константы — какая необходимость жестко фиксировать их наперед?
В 64-х битах такое разделение диктует железо.
Re[4]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
Pzz>>В 64-х битах такое разделение диктует железо.
ЕМ>Любое 64-разрядное железо диктует одну и ту же схему разделения адресов?
x86, я имею ввиду. Не удивлюсь, если и ARM тоже, в порядке подражания.
Re[6]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
Pzz>>x86, я имею ввиду.
ЕМ>Угу, а при проектировании любой ОС всегда наперед известно все без исключения железо, на котором она будет работать?
А на другом железе, возможно, константы будут другими, не?
Здравствуйте, Marty, Вы писали:
M>А на другом железе, возможно, константы будут другими, не?
Ну да, могут. И при таком подходе разбираться с ними придется и всем модулям ОС, которых это касается, и каждому стороннему софту отдельно. Когда можно было забить эти константы в один соответствующий модуль ОС, который отдавал бы их по запросу.
Re[9]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
M>>А на другом железе, возможно, константы будут другими, не?
ЕМ>Ну да, могут. И при таком подходе разбираться с ними придется и всем модулям ОС, которых это касается, и каждому стороннему софту отдельно. Когда можно было забить эти константы в один соответствующий модуль ОС, который отдавал бы их по запросу.
И чем лучше разбираться в ран-тайме лучше, чем разбираться в компайл-тайме?
Здравствуйте, Евгений Музыченко, Вы писали:
Pzz>>x86, я имею ввиду.
ЕМ>Угу, а при проектировании любой ОС всегда наперед известно все без исключения железо, на котором она будет работать?
При проектировании винды, да. Линукс, наверное не обязательно.
Re[8]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Sharowarsheg, Вы писали:
ЕМ>>Угу, а при проектировании любой ОС всегда наперед известно все без исключения железо, на котором она будет работать?
S>При проектировании винды, да. Линукс, наверное не обязательно.
Здравствуйте, Sharowarsheg, Вы писали:
ЕМ>>при проектировании любой ОС всегда наперед известно все без исключения железо, на котором она будет работать?
S>При проектировании винды, да.
И что, при проектировании NT в конце 80-х было известно, что она будет работать на MIPS, IA-64, Amd64, ARM?
Re[9]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>>при проектировании любой ОС всегда наперед известно все без исключения железо, на котором она будет работать?
S>>При проектировании винды, да.
ЕМ>И что, при проектировании NT в конце 80-х было известно, что она будет работать на MIPS, IA-64, Amd64, ARM?
NT третья, которая 3.5 и 3.51? Нет, очевидно. x86 и альфа, а всё остальное — как повезло.
Когда понадобилось x64, поправили ядро на новые константы, да и всё.
Re[10]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Sharowarsheg, Вы писали:
S>>Когда понадобилось x64, поправили ядро на новые константы, да и всё.
ЕМ>А что именно выиграли-то за счет констант?
Быстро, удобно, и практично. 3.51 NT, между прочим, запускалась на 8 MB оперативки. Наверное, и на 4 тоже, но я не пробовал.
Re[12]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Sharowarsheg, Вы писали:
ЕМ>>А что именно выиграли-то за счет констант? S>Быстро, удобно, и практично.
Первое верно — в данном случае, как я уже намекал, позволяло выиграть какую-нибудь десятитысячную долю процента от скорости/объема (сейчас это значение нужно уменьшить еще раз в тысячу). Достойный выигрыш, безусловно.
Второе верно исключительно в сиюминутном плане. Вспоминаем PC, в которой видеопамять была прибита гвоздями к A000, дисковое ПО — к C000, и т.п., и какие пляски требовались для использования свободных промежутков адресного пространства. А ведь даже тогда лишняя пара перемычек на плате совершенно терялась в стоимости любой платы, и все эти прибитые адреса могли бы определяться софтом через запросы к BIOS.
С виндой было то же самое — сперва казалось, что 2 Гб — это непредставимо большой объем ОЗУ, а потом пришлось извращаться с ужиманием пространства ядра до 1 Гб. Хотя не было никаких препятствий к тому, чтобы раскладывать ядро сверху вниз, и оно со всеми потрохами могло бы занимать 20-50-100 Мб, оставляя все остальное для пользовательских процессов. На хрена ему было в конце 80-х два гигабайта, когда даже сейчас 64-разрядная десятка и одного ядром не занимает?
Так что реально удобнее — экономия одного килобайта(это я еще сильно завысил) кода для изначальной поддержки динамического размещения, или весь тот геморрой, что потребовался для переделки и тестирования с 2+2 на 3+1?
Ну и практично это исключительно в одном плане — чтобы занять работой достаточное количество людей. Техническая практичность здесь отсутствует напрочь.
S>3.51 NT, между прочим, запускалась на 8 MB оперативки. Наверное, и на 4 тоже, но я не пробовал.
Верно. Так для чего ей были константно заложены те два гига только под одно ядро?
Re[13]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Ну и практично это исключительно в одном плане — чтобы занять работой достаточное количество людей. Техническая практичность здесь отсутствует напрочь.
S>>3.51 NT, между прочим, запускалась на 8 MB оперативки. Наверное, и на 4 тоже, но я не пробовал.
ЕМ>Верно. Так для чего ей были константно заложены те два гига только под одно ядро?
Чтобы я сейчас, через тридцать или сколько-там лет, мог запустить её с двумя гигами под ядро — примерно в 100 раз больше, чем исходно было задумано.
Re[14]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Sharowarsheg, Вы писали:
ЕМ>>Так для чего ей были константно заложены те два гига только под одно ядро?
S>Чтобы я сейчас, через тридцать или сколько-там лет, мог запустить её с двумя гигами под ядро — примерно в 100 раз больше, чем исходно было задумано.
А сумеете внятно объяснить, как на эту возможность повлияла именно константность раскладки адресного пространства?
Re[15]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>>Так для чего ей были константно заложены те два гига только под одно ядро?
S>>Чтобы я сейчас, через тридцать или сколько-там лет, мог запустить её с двумя гигами под ядро — примерно в 100 раз больше, чем исходно было задумано.
ЕМ>А сумеете внятно объяснить, как на эту возможность повлияла именно константность раскладки адресного пространства?
Эта конкретная константа, 2GB:2GB, просто не мешала этому использованию. В программах дофига констант, от которых требуется, чтобы они просто не были слишком плохи.
А константы.. они вполне соответствовала времени. Для DOS было достаточно 640 KB, а когда перестало быть достаточно, перестала существовать DOS, вместе с x86 реальным режимом. Так и для 32 бит достаточно, легко, и удобно сделать разделение 2:2 (и, на мой вкус, зря прикрутили 3:1). Старый софт, который уже не переписывается, всё ещё можно запустить, даже на физической машине, если нужно, но когда перестало быть достаточно 2 GB на процесс для нового софта, выкинули x86 вместе с 32-битным режимом, и всё новое, что могло бы сожрать больше 2 GB, написали на x64. На ближайшие десять лет x64 достаточно, и константа 8:8 TB или сколько там, вполне прекрасна.
А константность — это просто удобно. Кончилось поколение — кончилась константа, бери другую.
Re[16]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Sharowarsheg, Вы писали:
S>В программах дофига констант, от которых требуется, чтобы они просто не были слишком плохи.
Ну вот конкретно в Ваших программах, какими константами задаются адрес и максимальный размер кучи, адреса загрузки системных DLL и т.п.?
S>Для DOS было достаточно 640 KB, а когда перестало быть достаточно, перестала существовать DOS, вместе с x86 реальным режимом.
Это Вы уже все прочно забыли. HiMem/Emm386 появились в самом начале 90-х, и не от хорошей жизни. Иногда только эти 100-200 дополнительных килобайт и позволяли запустить софт, который иначе никак в память не помещался.
S>Так и для 32 бит достаточно, легко, и удобно сделать разделение 2:2
А зачем именно 2:2, а не m:n?
S>Старый софт, который уже не переписывается, всё ещё можно запустить, даже на физической машине, если нужно, но когда перестало быть достаточно 2 GB на процесс для нового софта, выкинули x86 вместе с 32-битным режимом, и всё новое, что могло бы сожрать больше 2 GB, написали на x64.
И это тоже наблюдения из мира розовых пони. Майкрософту бы нафиг не сдалось переделывать 2:2 в 3:1, если бы не массовое давление со стороны юзеров винды, в том числе жирных корпораций. А давили потому, что слишком большое количество софта просто некому было взять и переписать с 32 на 64. А еще потому, что в изрядном количестве софта разрядность указателя тоже явно или неявно используется, как константа, поэтому простая перекомпиляция не катит, а разбираться — нужны ресурсы. А еще под 64-разрядные 2k3 и XP, доля которых была очень мала на фоне 32-разрядных XP/2k, очень долго не было драйверов, кроме самых необходимых, и ситуация начала выправляться лишь после середины 2000-х, с выходом унифицированной 32/64-разрядной висты.
S>На ближайшие десять лет x64 достаточно, и константа 8:8 TB или сколько там, вполне прекрасна.
Ну да, один французский король тоже нечто подобное говаривал.
S>Кончилось поколение — кончилась константа, бери другую.
Хорошо, что математики, несколько сотен лет назад придумавшие заменять конкретные числа буквами, так не думали.
Re[18]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Sharowarsheg, Вы писали:
S>Конкретно в моих адреса загрузки системных DLL не задаются, я же не пишу загрузчик системных DLL.
Это потому, что разработчики ОС избавили Вас от этой заботы, а могли бы полениться и потребовать предоставления адреса для загрузки каждой DLL.
S>Размеры массивов (битность индексов) — задаются константами 16, 21, 24, и 48 (в разных местах и применительно к разным сущностям, естественно).
А как Вы решаете, по какому конкретно адресу разместить первичный блок для кучи, по какому — следующий, и так далее?
S>Не помню, чтобы что-то куда-то не помещалось. MultiEdit с дос навигатором помещались везде. Первое, что перестало помещаться, был DOOM, для которого сделали DOS4GW.
Ну, у кого-то спектр используемых под досом программ исчерпывался ME, DN и DOOM, а кто-то работал с системами верстки, разработки софта, с САПРами и т.п., которые вместе со всеми потребными драйверами в 640 кб категорически не помещались.
S>Чтобы по старшему биту можно было узнать, это пользовательский указатель, или ядерный.
Какую объективную экономию ресурсов это дает? И почему бы тогда не пойти дальше, обеспечив по одному биту различение указателей кода и данных, выгружаемого и невыгружаемого пулов, и т.п.?
S>У микрософта в то время было достаточно денег, чтобы купить все те "жирные" корпорации, а также купить пользователей и в рабство обратить.
Во-первых, кто б им все это продал? Во-вторых, на чем бы они зарабатывали после покупки?
S>Это собственные микрософтовские программисты, которых тоже перфекционизм одолел, захотели сделать все константы настраиваемыми, и обосрали всю малину — и, конечно, вызвали тыщщи синих экранов.
И отсюда, конечно же, вывод: "нужно продолжать устанавливать константы наперед, а когда они начинают сдерживать — выбрасывать все старое и делать новое"?
S>Математики не в состоянии сделать ничего практического. Например, нельзя построить мост из одних букв, какая бы ни была математика. В какой-то момент придётся подставить вместо букв хотя бы длину и ширину цифрами.
А если бы математики не создали унифицированных методов расчета моста на основе переменных, и каждый новый мост приходилось бы обсчитывать с нуля, используя эмпирические константы, которые для одних случаев избыточны, а для других — недостаточны?
Re[19]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Ну, у кого-то спектр используемых под досом программ исчерпывался ME, DN и DOOM, а кто-то работал с системами верстки, разработки софта, с САПРами и т.п., которые вместе со всеми потребными драйверами в 640 кб категорически не помещались.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Сперва были и 640 кб доступной обычной памяти,
Я плохо представляю себе процессор (особенно в то время) с неограниченными размерами адресных регистров и количеством проводов на внешней шине.
А если мы имеем 20 бит, то потеря примерно половины из них на разные ROM, I/O и прочее — вполне естественна.
EM> и жестко заданные адреса областей внешних устройств, хотя все это можно было запихать в BIOS, и возвращать конкретные адреса по запросам.
Хм, а то, что BIOS запускался с опять же константного адреса F000:FFF0, ты уже не считаешь? Что IDT реального режима сидела по адресу 0:0?
Там местами, конечно, злоупотребляли фиксацией типа "MDA память на 0xB80000", но конфликты происходили в других местах.
Я не вижу твёрдых причин делать эти параметры переменными и требовать извлекать из какого-то справочника, если нет нескольких таких устройств (ресурсов, в общем случае). Там, где было (как компорты, в количестве от 1 до 8), BIOS таки давал такие данные по запросу.
Всегда есть какие-то постоянные параметры. Начиная с кодов команд процессора
EM> Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1.
Эта переделка вообще потребовалась, потому что на 64 бита не успели быстро перейти. В остальном от неё проблем больше, чем пользы.
EM> В 64-разрядной винде снова 8+8 Тб. Сейчас читаю про макось — и там тоже сплошные явно определенные константы.
ЕМ>Это что-то вроде профессионального бега по граблям, или действительно есть серьезная необходимость изначально задавать эти адреса/размеры глобальными константами вместо того, чтобы определить их только внутри ядра, а всем внешним модулям (даже драйверам и системным службам) возвращать конкретные значения исключительно по запросам)?
Я не знаю, почему 8TB в винде. Но предполагаю, что это просто отражает некий порог, переход за который будет означать скачок в потреблении ресурсов, и этот скачок пока не оправдан.
Вот ещё вопрос: а то, что в автомобиле конкретные габариты и диаметр колёс, ты тоже будешь считать неоправданно зафиксированной константой?
А питающее напряжение в электросети?
The God is real, unless declared integer.
Re[6]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Pzz, Вы писали:
Pzz>>>В 64-х битах такое разделение диктует железо.
ЕМ>>Любое 64-разрядное железо диктует одну и ту же схему разделения адресов?
Pzz>x86, я имею ввиду. Не удивлюсь, если и ARM тоже, в порядке подражания.
У ARM основных линий 48 бит в адресе, но граница (старшие несколько бит) между двумя полуобластями регулируется.
Причём, адреса корневых страничных каталогов для обоих задаются раздельно. Это удобнее по сравнению с x86, где есть надоедливая проблема: если в результате управления памятью ядра меняются записи корневого каталога страниц, то эти изменения надо распространить на все процессы, и этим занимается отдельный блок контроля.
Вот что жаль, что в RISC-V вместо этого сделали практически полное повторение того, что в x86, и в результате там код MM должен тут тоже заниматься лишними плясками.
The God is real, unless declared integer.
Re[2]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Я плохо представляю себе процессор (особенно в то время) с неограниченными размерами адресных регистров и количеством проводов на внешней шине.
Пока смена архитектуры влекла за собой смену программной модели, и программы с 8-разрядных ПК не переносились автоматически на 16-разрядные, а с 16-разрядных — на 32-разрядные, разумно было исходить из разрядности архитектуры.
N>А если мы имеем 20 бит, то потеря примерно половины из них на разные ROM, I/O и прочее — вполне естественна.
Господь с Вами, где там естественность? Половина от мегабайта — 512 кб, а на "разные ROM, I/O и прочее" попервости уходило чуть больше сотни.
N>то, что BIOS запускался с опять же константного адреса F000:FFF0, ты уже не считаешь? Что IDT реального режима сидела по адресу 0:0?
Это все жалкие копейки, какой смысл их вообще упоминать? Коню понятно, что ряд основных параметров неизбежно приходится фиксировать. Но этих параметров очень немного, подавляющее большинство остальных выбирается произвольно.
N>злоупотребляли фиксацией типа "MDA память на 0xB80000", но конфликты происходили в других местах.
Я не о конфликтах, а о фиксации без явной необходимости, как таковой.
N>Я не вижу твёрдых причин делать эти параметры переменными и требовать извлекать из какого-то справочника, если нет нескольких таких устройств (ресурсов, в общем случае). Там, где было (как компорты, в количестве от 1 до 8), BIOS таки давал такие данные по запросу.
То есть, протокол PnP Вы считаете стратегической ошибкой, и адреса/порты/прерывания до сих пор следовало настраивать перемычками?
N>Всегда есть какие-то постоянные параметры. Начиная с кодов команд процессора
Боюсь, Вы не поняли исходной идеи. Или поняли, но из природного упрямства решили довести ее до абсурда.
EM>>в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1.
N>Эта переделка вообще потребовалась, потому что на 64 бита не успели быстро перейти.
А если бы изначально, вместо фиксации 2+2, определили M+N, то переделки не потребовалось бы вовсе, а реализация запроса M и N была бы, наверное, в тысячи раз дешевле той переделки.
N>В остальном от неё проблем больше, чем пользы.
Как практически от любого костыля, призванного исправить последствия грубой непродуманности.
N>то, что в автомобиле конкретные габариты и диаметр колёс, ты тоже будешь считать неоправданно зафиксированной константой?
Если Вы о габаритах кузова, то они соответствуют как раз исходным константам архитектуры — разрядности магистрали и адресного пространства. Неоправданной фиксацией было бы, например, искусственное, произвольное разделение багажника на секции, из-за которого невозможно было бы загрузить предмет, не помещающийся в секцию.
А параметры колес как раз почти везде плавающие — на многие автомобили можно ставить диски трех-четырех смежных диаметров, а на каждый из таких дисков — шины разной высоты и профиля. Но диски/шины — физические объекты, поэтому их разумно выпускать в ограниченном наборе стандартных размеров, а не бесконечное количество любых возможных вариаций.
N>А питающее напряжение в электросети?
Это тоже исходный параметр. Неоправданной фиксацией константы было бы, например, произвольное ограничение величины тока, потребляемого из одной розетки.
Вторичный источник питания, по большому счету, способен выдавать произвольное напряжение ниже максимально возможного, поэтому фиксацию тех же 5 В в источниках для USB можно было бы тоже считать произвольной, но на момент стандартизации USB, источники с напряжением и током, управляемыми по цифровой шине, были чрезмерно дороги, и фиксация 5 В была разумным компромиссом. А вот если бы сейчас, в разгар дешевых цифровых интерфейсов и микросхем на все случаи жизни, для нового массового универсального интерфейса зафиксировали напряжение, скажем в 10 В, это стало бы неоправданным ограничением.
Re: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Сперва были и 640 кб доступной обычной памяти, и жестко заданные адреса областей внешних устройств, хотя все это можно было запихать в BIOS, и возвращать конкретные адреса по запросам.
Вызов стоит времени, в отличие от зашитой константы. В плюсики, вон, сейчас constexpr подвезли, тоже ради скорости
ЕМ>Затем в 32-разрядной винде было 2+2 Гб, которые героическими усилиями переделали в 3+1. В 64-разрядной винде снова 8+8 Тб. Сейчас читаю про макось — и там тоже сплошные явно определенные константы.
Ну, тут я хз, но напрашивается простая идея, что из одного битика адреса сделали флаг. И да, такое переделать, если много куда проросло (а оно наверняка хорошо проросло) стоит героических усилий.
ЕМ>Это что-то вроде профессионального бега по граблям, или действительно есть серьезная необходимость изначально задавать эти адреса/размеры глобальными константами вместо того, чтобы определить их только внутри ядра, а всем внешним модулям (даже драйверам и системным службам) возвращать конкретные значения исключительно по запросам)?
Ты ёще не знаешь (ну, или знаешь), как на спектруме извращались ради быстродействия. Сейчас-то конечно да, гигагерцы уже никто не считает, а раньше считали такты.
Здравствуйте, Евгений Музыченко, Вы писали:
aik>>А причина может быть простая — одним битом удобно управлять трафиком на системной шине: нет бита == RAM, есть бит == MMIO, и это, например, прибито гвоздями в железе.
ЕМ>В каких-нибудь микроконтроллерах это может быть и удобным, но не в вычислительных же (в широком смысле) системах.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Пока смена архитектуры влекла за собой смену программной модели, и программы с 8-разрядных ПК не переносились автоматически на 16-разрядные, а с 16-разрядных — на 32-разрядные, разумно было исходить из разрядности архитектуры.
8ми разрядные по идее на 16ти-разрядные должны бы переносится вообще без проблем, не вижу каких-то сложностей. А есть какая-то конкретика?
N>>то, что BIOS запускался с опять же константного адреса F000:FFF0, ты уже не считаешь? Что IDT реального режима сидела по адресу 0:0?
ЕМ>Это все жалкие копейки, какой смысл их вообще упоминать? Коню понятно, что ряд основных параметров неизбежно приходится фиксировать. Но этих параметров очень немного, подавляющее большинство остальных выбирается произвольно.
Тебе сейчас жалкие копейки, а тогда и другим это было важно.
ЕМ>А если бы изначально, вместо фиксации 2+2, определили M+N, то переделки не потребовалось бы вовсе, а реализация запроса M и N была бы, наверное, в тысячи раз дешевле той переделки.
Могу предположить, что тогда изначально всё было бы сильно дороже
N>>В остальном от неё проблем больше, чем пользы.
ЕМ>Как практически от любого костыля, призванного исправить последствия грубой непродуманности.
Или, наоборот, продуманности в рамках той ситуации. Проблема в том, что за модернизацию никто платить не хочет, и висит груз совместимости. А сразу сделать офигенски на все времена — это малореально, и на момент первой реализации слишком дорого.
ЕМ>Вторичный источник питания, по большому счету, способен выдавать произвольное напряжение ниже максимально возможного, поэтому фиксацию тех же 5 В в источниках для USB можно было бы тоже считать произвольной, но на момент стандартизации USB, источники с напряжением и током, управляемыми по цифровой шине, были чрезмерно дороги, и фиксация 5 В была разумным компромиссом. А вот если бы сейчас, в разгар дешевых цифровых интерфейсов и микросхем на все случаи жизни, для нового массового универсального интерфейса зафиксировали напряжение, скажем в 10 В, это стало бы неоправданным ограничением.
Ну, вот видишь, ты сам понимаешь, что ограничения рождались не просто так
Здравствуйте, Marty, Вы писали:
M>Вызов стоит времени, в отличие от зашитой константы.
И сколько тысяч раз в секунду Вам потребовалось бы получать фактический размер пользовательского АП?
M>В плюсики, вон, сейчас constexpr подвезли, тоже ради скорости
Сейчас?
M>напрашивается простая идея, что из одного битика адреса сделали флаг.
Именно так — некоторые функции ядра проверяли его командой test. Но с тем же успехом могли бы сравнивать командой cmp с переменной. Все эти функции, без исключения, вызываются относительно редко. Таких, где стоило бы экономить несколько тактов на обращении к памяти, там и близко нет.
M>такое переделать, если много куда проросло (а оно наверняка хорошо проросло) стоит героических усилий.
А могли бы изначально чуть подумать, и не геройствовать потом. Разве что исходно планировалось потом пилить бюджеты.
M>Ты ёще не знаешь (ну, или знаешь), как на спектруме извращались ради быстродействия. Сейчас-то конечно да, гигагерцы уже никто не считает, а раньше считали такты.
Когда-то я сам считал такты и байты, но исключительно по причинам объективного характера.
Re[3]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
M>>Вызов стоит времени, в отличие от зашитой константы.
ЕМ>И сколько тысяч раз в секунду Вам потребовалось бы получать фактический размер пользовательского АП?
Мне, при программировании прикладных приложений — вроде ни разу, а в ядре вполне может быть востребованной операцией.
M>>В плюсики, вон, сейчас constexpr подвезли, тоже ради скорости
ЕМ>Сейчас?
Ну да. Только в 11ом стандарте появились, но убогие, и их постоянно дорабатывают
M>>напрашивается простая идея, что из одного битика адреса сделали флаг.
ЕМ>Именно так — некоторые функции ядра проверяли его командой test. Но с тем же успехом могли бы сравнивать командой cmp с переменной. Все эти функции, без исключения, вызываются относительно редко. Таких, где стоило бы экономить несколько тактов на обращении к памяти, там и близко нет.
Ну хз. 640 Кб хватит всем. Кто ж думал, что всё так бурно попрёт, и будут писать софт на жиэсах. А заранее всё пытаться предусмотреть — это даёт высокую степень вероятности, что продукт так никогда и не выйдет.
M>>такое переделать, если много куда проросло (а оно наверняка хорошо проросло) стоит героических усилий.
ЕМ>А могли бы изначально чуть подумать, и не геройствовать потом. Разве что исходно планировалось потом пилить бюджеты.
Здравствуйте, Marty, Вы писали:
ЕМ>>В каких-нибудь микроконтроллерах это может быть и удобным, но не в вычислительных же (в широком смысле) системах.
M>В них тоже, почему нет
Где-нибудь в 80-х, когда декодеры адресов шины нередко делали на элементарной рассыпухе, это имело хоть какой-то смысл. В 90-х, когда все уже было на [С]БИС — почти никакого.
Re[5]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>>В каких-нибудь микроконтроллерах это может быть и удобным, но не в вычислительных же (в широком смысле) системах.
M>>В них тоже, почему нет
ЕМ>Где-нибудь в 80-х, когда декодеры адресов шины нередко делали на элементарной рассыпухе, это имело хоть какой-то смысл. В 90-х, когда все уже было на [С]БИС — почти никакого.
Микроконтроллеры сейчас тоже не на рассыпухе, но для них ты это оставляешь
Здравствуйте, Marty, Вы писали:
M>в ядре вполне может быть востребованной операцией.
В ядре эта операция востребована только при проверке адресов, а такие проверки сопутствуют только достаточно редким и/или масштабным операциям. Разница между проверкой одного разряда и сравнением с переменной там даже в тестах будет ниже статистических погрешностей.
M>заранее всё пытаться предусмотреть — это даёт высокую степень вероятности, что продукт так никогда и не выйдет.
Да, когда предусматривание требует сколько-нибудь заметных затрат. А затраты на обоснованный выбор фиксированной границы — 640, 512 или 736 — по определению больше затрат на реализацию через переменную и системный запрос. Только выбор наобум может быть дешевле.
Re[5]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
M>>в ядре вполне может быть востребованной операцией.
ЕМ>В ядре эта операция востребована только при проверке адресов, а такие проверки сопутствуют только достаточно редким и/или масштабным операциям. Разница между проверкой одного разряда и сравнением с переменной там даже в тестах будет ниже статистических погрешностей.
Не буду спорит, не располагаю информацией.
M>>заранее всё пытаться предусмотреть — это даёт высокую степень вероятности, что продукт так никогда и не выйдет.
ЕМ>Да, когда предусматривание требует сколько-нибудь заметных затрат. А затраты на обоснованный выбор фиксированной границы — 640, 512 или 736 — по определению больше затрат на реализацию через переменную и системный запрос. Только выбор наобум может быть дешевле.
Здравствуйте, netch80, Вы писали:
N>Где это у нас автоматический перенос программ?
В винде. 32-разрядная программ автоматически идет под 64-разрядной виндой в той же линейной модели, а 16-разрядная идет под 32-разрядной в искусственно создаваемой 16-разрядной модели.
N>A0000-BFFFF видеопамять всех видов N>C0000-DFFFF область расширителей N>E0000-FFFFF BIOS (да, занимал сильно больше 64KB, начиная ещё с AT)
Это все устаканивалось почти десяток лет, а изначально выбор границы в 640 кб был практически произвольным. В итоге, как известно, в одних машинах было множество неиспользуемых дыр в АП, а в других все служебное не влезало в 384 кб, и приходилось переключать.
N>Ну да, с запасом.
Да, выбранным практически наугад.
N>И не надо вспоминать про "хватит всем", этот миф давно развенчан.
Миф — то, что это было сказано Гейтсом. Реальность — то, что примерно в том же смысле цифра была озвучена на каком-нибудь совещании, в качестве наиболее приемлемой оценки. Хотя фиксации конкретной цифры вовсе не требовалось.
N>Вот я и пытаюсь понять, где у тебя граница между "ряд основных" и "подавляющее большинство остальных".
Логика предельно проста, она такая же, как и в программировании: если конкретная величина заранее неизвестна, то она оформляется в виде переменной. Если затраты на работу с переменной чрезмерно велики, то для оптимизации используются приемы вроде констант или макросов. Если константа самоочевидна (единица как минимальное натуральное число, двойка как основание двоичной системы и т.п.), то нет смысла вводить переменные или константы One/Two.
N>когда стало _легко_ делать вариабельные адреса, то это стали делать.
Когда было тяжело сделать один вариабельный адрес на всю систему?
N>Заметь, MCA, на которой это впервые появилось, это ~1987. PCI это 1991. Прогресс был стремительным за это время, и возможность перешла из дорогого сегмента в общий. Но и то — вначале PCI имел подпорки для AGP, для ATA и ещё для чего-то, отдельными требованиями в стандарте. А это такая же фиксация.
N>описания северного моста, то у него на корневой PCI шине дофига фиксированных устройств
Да и ради бога — это не добавляет сколько-нибудь заметных неудобств в процесс аппаратного проектирования/сопряжения в целом, где многое завязано на физические параметры. Ситуация, в которой северный мост вдруг изымается из одной системы и встраивается в другую, маловероятна. Ситуация, в которой это происходит с программой, почти неизбежна.
N>не из какого-то упрямства, а в порядке поиска границ. Ты сам допускаешь, что какие-то значения должны быть константными. Но чётких критериев разграничения не дал.
Это границы разумного.
N>Какие нафиг N и какие M?
M — объем адресного пространства, доступного пользователю, N — объем АП ядра.
N>Чему они могли бы быть равны?
Конкретным объемам, доступным в данной системе. Во времена, когда 2 Гб стало не хватать уже много кому, объем всего ядра не превышал нескольких десятков мегабайт. Соответственно, M было бы равно 3.9 Гб, а N — 0.1 Гб. 3.9 Гб для прикладных процессов, за совершенно ничтожную цену.
N>Вот потому и делали 2:2, 3:1 и для особых извращенцев — 3.5:0.5
А могли бы сразу добавить один конфигурационный параметр для границы, и избежать частных случаев навсегда.
N>расскажи, в чём именно непродуманность.
В упор не понимаю, что еще нужно рассказать. Но есть отчетливое впечатление, что Вы упорно косите под дурачка.
N>Им соответствует функциональность типа "возить до 4 человек весом до 100 кг с грузом в объёме до двух обычных чемоданов, со скоростью до 150 км/ч". А какого размера будет при этом машина — это уже как раз вопрос реализации.
И какова вероятность, что ширина машины будет превышать ее длину? А вероятность того, что в ряду будет сидеть нецелое количество пассажиров?
EM>>Неоправданной фиксацией было бы, например, искусственное, произвольное разделение багажника на секции
N>У меня что в старой, что в новой машине такое разделение есть. Под основным дном багажника место для запасного колеса.
У Вас не то разделение. Разделение, о котором я говорю — это стенка поперек багажника по всей его высоте, чтобы Ваш электронасос положить в одну из секций. Изначально она стоит посредине, но за конечную плату ее можно передвинуть на полметра в сторону. Места в малой секции все равно будет больше, чем нужно для насоса, но класть туда что-то еще будет запрещено ПДД.
N>я туда рядом с колесом закидываю всякие мелочи типа ключей, но не смог впихнуть электронасос для колёс.
А то колесо в каждой машине разного размера, да?
N>Для типового применения всё сделано правильно.
Если бы делали так же, как сделано в NT, то вместо багажника у Вас был бы прицеп, в котором одиноко болталось бы одно запасное колесо. В премиальных моделях этих колес было бы четыре, но размер прицепа всегда был бы одинаковым.
N>Большинство наших розеток ограничены 10A.
Но Вы же знаете, почему, да?
N>Я всё-таки не вижу, где эти ограничения были бы настолько неоправданны, что заставили бы страдать индустрию без причины на длительный срок.
Ну, раз никто не страдал по поводу нехватки сперва 640 кб, потом двух гигабайт, а затем трех, то надо признать, что XMS/EMS, PAE и тому подобное создавались, внедрялись и переделывались из чистого энтузиазма, без малейшей производственной надобности.
N>как только упирались в них, достаточно быстро находился вариант решить проблему переходом за следующий порог, который при этом был в разы дальше.
То есть, классика: сперва создаем проблему, затем героически ее решаем.
N>чтобы без порога вообще — такого не бывало, потому что мы в реальном мире.
Реальность мира диктует только размер переменной для хранения границы доступного АП: в 32-разрядных системах — четыре байта, в 64-разрядных — восемь.
Re[6]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Marty, Вы писали:
M>Микроконтроллеры сейчас тоже не на рассыпухе, но для них ты это оставляешь
Микроконтроллеры, в большинстве своем — сильно ограниченные изделия, где при гигантских тиражах ощутимы даже небольшие излишества. Я уже как-то говорил, что Ваши любимые STM32 — капля в море всех МК, выпускаемых и применямых по миру.
Ну и сравните вероятность, с которой программа, сделанная для МК одной модели, без доработки вдруг окажется в другой, с вероятностью такой миграции с одной винды на другую.
Re[7]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
M>>Микроконтроллеры сейчас тоже не на рассыпухе, но для них ты это оставляешь
ЕМ>Микроконтроллеры, в большинстве своем — сильно ограниченные изделия, где при гигантских тиражах ощутимы даже небольшие излишества. Я уже как-то говорил, что Ваши любимые STM32 — капля в море всех МК, выпускаемых и применямых по миру.
Наши любимые STM32 — это большая часть мира микроконтроллеров. Потому что не надо сравнивать какой-нибудь пик, который один раз запрограммировал инженер-железячник, и который ушел в миллионную серию, и STM32, для которых размер серии измеряется единицами, десятками, может быть сотнями или тысячами штук, на которых пилятся всевозможные изделия самого разного вида.
В количестве произведённых единиц пик или msc51 конечно уделает STM, но не по разнооборазию решаемых задач.
ЕМ>Ну и сравните вероятность, с которой программа, сделанная для МК одной модели, без доработки вдруг окажется в другой, с вероятностью такой миграции с одной винды на другую.
А МК одной модели — это как? В текущей конторе есть ровно два вполне конкретных МК, на которых пилят всё, один из семейства F4, другой из F1. Вот вообще конкретные версии, F429II и ни шагу влево вправо. В предыдущей конторе — это могли быть STM32F1/F3/F4/L0, причем в любой их версии, начиная от количества оперативы и флеша, и заканчивая наличием доступной периферии.
Здравствуйте, Marty, Вы писали:
M>Наши любимые STM32 — это большая часть мира микроконтроллеров.
Какого именно мира? Как вы его измеряете?
M>не надо сравнивать какой-нибудь пик, который один раз запрограммировал инженер-железячник, и который ушел в миллионную серию
И применений таких пиков по миру — десятки тысяч минимум. Столько же AVR'ов, еще больше Holtek'ов и прочих.
M>STM32, для которых размер серии измеряется единицами, десятками, может быть сотнями или тысячами штук, на которых пилятся всевозможные изделия самого разного вида.
И сколько это будет, если все перемножить?
M>В количестве произведённых единиц пик или msc51 конечно уделает STM, но не по разнооборазию решаемых задач.
А что, распространенность в мире обсуждаемой винды измеряется разнообразием решаемых на ней задач? Подавляющее большинство экземпляров обслуживает браузер, игры и что-нибудь офисное.
M>А МК одной модели — это как?
Это с одинаковой конфигурацией выводов, портов, памяти, таймеров, ЦАП/АЦП и прочего.
Re[9]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
M>>Наши любимые STM32 — это большая часть мира микроконтроллеров.
ЕМ>Какого именно мира? Как вы его измеряете?
На них решается большинство задач
M>>не надо сравнивать какой-нибудь пик, который один раз запрограммировал инженер-железячник, и который ушел в миллионную серию
ЕМ>И применений таких пиков по миру — десятки тысяч минимум. Столько же AVR'ов, еще больше Holtek'ов и прочих.
Не путай количество экземпляров с количеством применений
M>>STM32, для которых размер серии измеряется единицами, десятками, может быть сотнями или тысячами штук, на которых пилятся всевозможные изделия самого разного вида.
ЕМ>И сколько это будет, если все перемножить?
Полагаю, гораздо больше, чем однотипных изделий хоть какого типа
M>>В количестве произведённых единиц пик или msc51 конечно уделает STM, но не по разнооборазию решаемых задач.
ЕМ>А что, распространенность в мире обсуждаемой винды измеряется разнообразием решаемых на ней задач? Подавляющее большинство экземпляров обслуживает браузер, игры и что-нибудь офисное.
Я потерял нить беседы, если честно
M>>А МК одной модели — это как?
ЕМ>Это с одинаковой конфигурацией выводов, портов, памяти, таймеров, ЦАП/АЦП и прочего.
Тогда те же STM32F4 — это сотни, если не тысячи разных вариантов
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Где это у нас автоматический перенос программ?
ЕМ>В винде. 32-разрядная программ автоматически идет под 64-разрядной виндой в той же линейной модели, а 16-разрядная идет под 32-разрядной в искусственно создаваемой 16-разрядной модели.
Ну вот ты сам себе и ответил, что та 16-битная была уже искусственно созданной. В случае же 32/64 это тоже намеренно оставленный переходник. Могли и не оставлять, но тогда переключение между legacy и long (в их терминах) было бы сильно дороже.
А в исходниках ты тем более так легко не сделаешь.
N>>A0000-BFFFF видеопамять всех видов N>>C0000-DFFFF область расширителей N>>E0000-FFFFF BIOS (да, занимал сильно больше 64KB, начиная ещё с AT) ЕМ>Это все устаканивалось почти десяток лет, а изначально выбор границы в 640 кб был практически произвольным.
Да. А теперь обрати внимание, что первые PC могли иметь вообще 16KB памяти. Даже меньше одного сегмента. Это самая дешёвая конфигурация. А память тогда (1981) стоила 8.8$/kB, то есть 64 обходилось бы в 560$ тогдашних (а для теперешних надо умножить на 5-7).
Итого посчитай по нынешнему: 2800$/64KB. 28000$/640KB.
Никто такой памяти не ставил до середины 80-х, и то только самые толстые.
Вот примерно с 1986-87 стало возможно заполнить эти 640 полностью для большинства, когда цена реально драматически упала (1986 это 300$/MB, 1987 уже 150 — о таком прогрессе сейчас можно только тоскливо мечтать).
Конечно, сидя в СССР за занавесом мы с тобой эту историю пропустили. И теперь тебе кажется, что эта граница могла быть достигнута с самого начала.
А тогда думали иначе. При том, что архитектуры более широкого плана были известны давно, про 386-й с момента его выхода (1985) знал каждый в теме, это не считалось проблемой. Кому мало этой памяти — идите в расширители и в 32 бита.
Вот почему окончательный переход с реального режима и MS-DOS застрял фактически лет на 10 (когда с Win95 стали забывать про DOS), вот это действительно серьёзный повод обсудить. То ли расчёты прогресса оказались поспешными, то ли авторы софта застыли в кривой позе и потеряли время непонятно на чём. Ну Microsoft экспериментировал с Xenix, это да. NT они начали рисовать году в 87, судя по первым копирайтам.
Тут я бы послушал, какие грабли и где были расставлены. У кого есть ссылки с хорошим описанием, поделитесь.
EM> В итоге, как известно, в одних машинах было множество неиспользуемых дыр в АП, а в других все служебное не влезало в 384 кб, и приходилось переключать.
Я согласен с тем, что область видеопамяти надо было бы переместить повыше, тогда мы бы упёрлись не в 640, а в 768K или даже выше (если взять видеорежим попроще). Тут недоработали. Но опять же со взглядом из 1981 считалось, что прежде чем упёрлись бы в этот предел, архитектура поменялась бы так, что он перестал бы быть важным.
Кстати, ещё один момент тут — Intel при проектировании 286 мог сделать, что эти области мапятся в верхний предел адресного пространства. Это было сделано ещё в PDP-11: 16-битные адреса с 0b111 вначале получали для обеих размерностей (18 и 22 бита) все старшие единицы, если выключен DAT. Но Intel как всегда протупил на ровном месте, и мы получили проблему в виде legacy 1MB блока.
N>>Ну да, с запасом. ЕМ>Да, выбранным практически наугад.
А тогда и невозможно было иначе. Что оно составило больше половины адресного пространства — уже было успехом для последующей работы. Могли и 256KB ограничиться, а дальнейшее позанимать на разные разности. Может, это было бы и лучше в том плане, что переход на следующую разрядность прошёл бы более ровным путём.
N>>Вот я и пытаюсь понять, где у тебя граница между "ряд основных" и "подавляющее большинство остальных". ЕМ>Логика предельно проста, она такая же, как и в программировании: если конкретная величина заранее неизвестна, то она оформляется в виде переменной. Если затраты на работу с переменной чрезмерно велики, то для оптимизации используются приемы вроде констант или макросов. Если константа самоочевидна (единица как минимальное натуральное число, двойка как основание двоичной системы и т.п.), то нет смысла вводить переменные или константы One/Two.
Спроецируем на IBM PC. Если я тебя понял правильно, то пока мы не можем ничего сделать с 20-битной адресацией, нам нужно было бы сделать какую-то ячейку в, как было принято, BIOS data area с указанием, где сидит видеопамять (так как это у нас основная граница). Пусть в первых версиях она сидела от 0xA0000. Но пришло время ужаться — убрали неиспользуемый кусок в ROM extension area и в extended BIOS и посадили память, например, 0xE8000. В результате имеем уже не 640KB, а 928KB. Так?
И тогда я скажу в третий, наверно, раз за этот комментарий, что когда шёл стремительный прогресс (быстрее того 2 раза за 1.5-2 года что по закону Мура), эффект типа "в 2 раза" никого не интересовал, цикл от идеи до внедрения это 3-5 лет и потому эффект нужен такой, чтобы давал минимум 16 раз, а лучше 256. Вот переход на 24 бита адреса в 286 и 32 в 386 это сила, а 928 вместо 640 это ни о чём. И таки я очень рекомендую вернуться к вопросу, почему MS-DOS с реальным режимом умерли не в 1985, а в 1995 ("умерли" тут в смысле "перестали вкладываться новые силы в разработку под них с нуля").
N>>когда стало _легко_ делать вариабельные адреса, то это стали делать. ЕМ>Когда было тяжело сделать один вариабельный адрес на всю систему?
Какой именно из? Их там несколько.
N>>не из какого-то упрямства, а в порядке поиска границ. Ты сам допускаешь, что какие-то значения должны быть константными. Но чётких критериев разграничения не дал. ЕМ>Это границы разумного.
Вот и вопрос в согласовании понятия "разумное", при условии, что ты, похоже, не понимаешь, в какой обстановке всё это происходило. И нет, я не про политику.
N>>Чему они могли бы быть равны? ЕМ>Конкретным объемам, доступным в данной системе. Во времена, когда 2 Гб стало не хватать уже много кому, объем всего ядра не превышал нескольких десятков мегабайт. Соответственно, M было бы равно 3.9 Гб, а N — 0.1 Гб. 3.9 Гб для прикладных процессов, за совершенно ничтожную цену.
И снова упускаешь две вещи.
1) Это ещё период заметного роста свойств, хоть и не такой безумный, как в 80-х. Приложения, которым не хватает 2GB, но хватает 3.9GB, очень редки — это узкая полоса. Большинству или достаточно меньше (99+%), или не хватает уже 4GB (1-%). Основное направление развития уже давно это переход на 64 бита, причём Windows на x86 в этом смысле глубокая отсталая провинция. Юниксы начали переходить ещё в 90-х, у нас была машинка на Alpha в 1999. MIPS64 появился в 1999, ну нам не достался SystemZ — это 2000. Когда там первая Windows на amd64? 2005?
2) Вся архитектура ядер оптимизирована на случай, когда всю оперативную память плюс адресное пространство ввода-вывода можно полностью отобразить на ту часть общего адресного пространства, что отведена ядру. В случае 2+2 и оперативной памяти до 1.5GB это выполняется. В случае, например, 4GB RAM уже нет. При 3+1, 3.5+0.5 — тоже нет. При невыполнении этого главного условия начинаются частые переключения страниц и перегонки между ними. В Linux явно ругались на это, что надо вводить так называемые bounce buffers. Затраты времени на эти операции. И зачем оно такое для менее 1% пользователей, если при переходе на 64 это снова не будет нужно?
Повторюсь, ты тут один-к-одному провинциал из села, который не видел выше двухэтажного дома, начинаешь рассказывать, как строить пятиэтажные тем, кто только что закончил квартал как минимум 9- и 16-этажных, а в планах следующий на 25. Сконцентрировавшись на Windows, ты тут пропустил, где в этом плане шёл прогресс задолго до.
N>>Вот потому и делали 2:2, 3:1 и для особых извращенцев — 3.5:0.5 ЕМ>А могли бы сразу добавить один конфигурационный параметр для границы, и избежать частных случаев навсегда.
Не нужно. См. выше.
N>>расскажи, в чём именно непродуманность. ЕМ>В упор не понимаю, что еще нужно рассказать. Но есть отчетливое впечатление, что Вы упорно косите под дурачка.
Спасибо. Я не буду столь же интенсивен в плане личных качеств, но см. выше про провинциала. Проблемы, которые кажутся вам критичными, не являлись такими для большинства или по крайней мере не планировались такими.
[skip аналогии, которые пошли не туда и не актуальны вообще]
N>>Я всё-таки не вижу, где эти ограничения были бы настолько неоправданны, что заставили бы страдать индустрию без причины на длительный срок.
ЕМ>Ну, раз никто не страдал по поводу нехватки сперва 640 кб, потом двух гигабайт, а затем трех, то надо признать, что XMS/EMS, PAE и тому подобное создавались, внедрялись и переделывались из чистого энтузиазма, без малейшей производственной надобности.
Нет, это уже демагогия с вашей стороны. А вот на что рекомендую обратить внимание по каждой этой технологии, это во сколько раз они расширяли возможности.
N>>как только упирались в них, достаточно быстро находился вариант решить проблему переходом за следующий порог, который при этом был в разы дальше. ЕМ>То есть, классика: сперва создаем проблему, затем героически ее решаем.
"Героически" было только по причине неоправданной задержки с MS-DOS, и я уже в 4-й раз вынужден сказать, что именно её продлённое существование тут является ключом и вопросом на полезное обсуждение (хотя бы в историческом плане).
Даже задержка создания общедоступной 64-битной Windows, по сравнению с Linux, NetBSD и прочими, которые к моменту выхода amd64 в железе были полностью готовы — не насколько интересна и существенна.
N>>чтобы без порога вообще — такого не бывало, потому что мы в реальном мире. ЕМ>Реальность мира диктует только размер переменной для хранения границы доступного АП: в 32-разрядных системах — четыре байта, в 64-разрядных — восемь.
И снова не учитываете, что действия типа "а сейчас мы забабахаем все 64 бита на физический адрес!" приведут просто к тому, что подорожавший на 20% продукт не выиграет соревнования с конкурентами.
Здравствуйте, Евгений Музыченко, Вы писали:
aik>>А причина может быть простая — одним битом удобно управлять трафиком на системной шине: нет бита == RAM, есть бит == MMIO, и это, например, прибито гвоздями в железе.
ЕМ>В каких-нибудь микроконтроллерах это может быть и удобным, но не в вычислительных же (в широком смысле) системах.
Ну так и при проектировании процессора тоже может быть удобным.
Просто на тот момент это была заведомо большая величина, и проектировщику на тот момент наверное казалось совсем без разницы, 2 или 3Гб, все-равно овердофига.
А если кто и задумывался о будущем, вполне справедливо мог рассудить, что к тому времени и архитектура другая будет.
Просто никто не впрягается менять архитектуру, пока сильно не прижмет.
Re[5]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Я правильно угадал, что больше всего жрет браузер? У себя я еще не видел более жручего приложения (в игры не играю, фото/видео не монтирую).
Так они тоже не сами к этому пришли. Лучше переформулировать, что жрёт не браузер, а сайты в нём.
WX>>у блогов и форумов вроде Хабры должны быть такие же системные требования как у Фотошопа. Впрочем, JavaScript это в целом раковая опухоль интернета... ЕМ>Это полностью поддерживаю.
Я честно не думаю, что от замены JS на что-то другое, менее тупое, тут стало бы сильно легче.
Главное таки это возможность сделать толстый сайт и не получить немедленной реакции на это, как в случае установки локальной программы. Каждый месяц по чуть-чуть, по паре процентов увеличивать объём кода и работы на клиентской стороне — и через пять лет существующих процессора и памяти перестаёт хватать и характеристики надо удваивать. Потом придёт следующий сайт... Нет, веб тут в целом сам по себе болезнь, а не конкретное средство его локального оживляжа.
ЕМ>Что в тех мейнфреймах было "специально аппаратного" для поддержки полной загрузки БД в память, чего нет хотя бы в i486?
+1. Меня этот пассаж тоже удивляет.
The God is real, unless declared integer.
Re[6]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Так они тоже не сами к этому пришли. Лучше переформулировать, что жрёт не браузер, а сайты в нём.
Это вечная проблема перекладывания ответственности. "Наркоторговцы не виноваты — они лишь отвечают на возрастающий спрос, работайте с потребителями".
N>Я честно не думаю, что от замены JS на что-то другое, менее тупое, тут стало бы сильно легче.
Сильно легче стало бы не от замены, а от изначального ограничения активности ваб-страницы чем-нибудь вроде расширенного CSS, где реализован разумный набор средств взаимодействия (те же спойлеры, деревья, простые реакции на действия пользователя и т.п.). Для подавляющего большинства информационных сайтов этого бы хватило, а кому надо интерактивности — делайте приложения, хоть нативные под ОС, хоть универсальные под единую VM, роль которой сейчас исполняют браузеры.
Хреново ведь стало вовсе не от того, что появился JS, а от того, что его впихнули в заведомо неподходящее средство. Человеку нужно средство доступа к базовым сетевым сервисам, а в нагрузку он получает еще один компьютер. То же самое случилось и с телефонами — человеку нужно средство связи, а в нагрузку он получает кучку средств доставки рекламы и привязки к поставщикам услуг.
N>веб тут в целом сам по себе болезнь
Болезнь — не веб, а его превращение в балаган.
Re[6]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Никто такой памяти не ставил до середины 80-х, и то только самые толстые.
Я у Чена наткнулся на описание реального косяка с Win 95, которая отказывалась грузиться, если памяти было больше 480 Мб. То, что для "первичной кучи" отводился блок фиксированного размера, это еще ладно, но то, что наличие памяти, описание которой не влезало в этот блок, приводило к отказу в загрузке — это уже за пределами разумного. Это, блин, уровень студента-второкурсника.
Re[7]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Никто такой памяти не ставил до середины 80-х, и то только самые толстые. ЕМ>Я у Чена наткнулся на описание реального косяка с Win 95, которая отказывалась грузиться, если памяти было больше 480 Мб. То, что для "первичной кучи" отводился блок фиксированного размера, это еще ладно, но то, что наличие памяти, описание которой не влезало в этот блок, приводило к отказу в загрузке — это уже за пределами разумного. Это, блин, уровень студента-второкурсника.
Да, хороший пример — хоть и к обсуждаемому вопросу относится весьма боком.
Он такой был далеко не единственный. Например, до времён где-то первой XP, видимый размер ATA дисков обрезался до остатка от деления на 32GB. Причём молча (просто видело мелкую цифру).
Сейчас основной вопрос в скорости реакции на такое. В до-интернетовские времена, когда невозможно было быстро раздавать обновления, лечить могли годами.
А в целом сам стиль кодирования на C/C++ провоцирует на такие ошибки.
The God is real, unless declared integer.
Re[8]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>видимый размер ATA дисков обрезался до остатка от деления на 32GB.
N>в целом сам стиль кодирования на C/C++ провоцирует на такие ошибки.
Да ладно. В каком языке есть хоть какая-то защита от неправильного применения хоть деления с остатком, хоть обычного деления?
С 480 Мб для Win 95 косяк был не в том, что выбрали фиксированный разумно достаточный размер пула, а то, что вместо игнорирования "лишней" памяти получился отказ в загрузке всей системы. Если и ставился вопрос "а вдруг памяти окажется до хренища?", то ответ "в таком случае надо выйти из ситуации корректно" явно не фигурировал.
Re[8]: Откуда такая неизбывная приверженность к константам?
П>One of my friends got 96MB of memory on his machine to test that we didn’t tank under “insanely huge memory configurations” and we all drooled.
То есть, если Вам вдруг приспичит подключить к одной машине, скажем, 25 или 50 последовательных портов, и система откажется грузиться, Вы воспримете это, как должное?
Re[9]: Откуда такая неизбывная приверженность к константам?
П>>One of my friends got 96MB of memory on his machine to test that we didn’t tank under “insanely huge memory configurations” and we all drooled.
ЕМ>То есть, если Вам вдруг приспичит подключить к одной машине, скажем, 25 или 50 последовательных портов, и система откажется грузиться, Вы воспримете это, как должное?
Нет. Но вот почему-то когда речь заходит о линуксе, там сразу начинают говорить, что покупайте совместимое оборудование. А тут наоборот — если мне надо подключить 25-50 портов, то я бы озадачился вопросом, какая ОС позволит мне работать с таким количеством портов. Если ОС не грузиться — хорошо, вычеркиваем эту ОС из списка.
Re[9]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>видимый размер ATA дисков обрезался до остатка от деления на 32GB. N>>в целом сам стиль кодирования на C/C++ провоцирует на такие ошибки. ЕМ>Да ладно. В каком языке есть хоть какая-то защита от неправильного применения хоть деления с остатком, хоть обычного деления?
Смотря что считать защитой и что — языком.
В современных процессорах, как правило, деление на 0 или деление с переполнением не вызывает исключения. RISC-V обещает, что беззнаковое деление на 0 даст ~0 (как UINT_MAX).
Язык может генерировать исключение на это или подставлять такой же безопасный дефолт. Если исключение отражается в видимой диагностике, это можно было бы написать.
Но я не про деление как таковое (кстати, почему ты думаешь про деление? может, там что-то другое было), а про вообще подход, что не предполагается обрабатывать ошибки в арифметике, потому что нет возможности их отобразить в результате операции.
ЕМ>С 480 Мб для Win 95 косяк был не в том, что выбрали фиксированный разумно достаточный размер пула, а то, что вместо игнорирования "лишней" памяти получился отказ в загрузке всей системы. Если и ставился вопрос "а вдруг памяти окажется до хренища?", то ответ "в таком случае надо выйти из ситуации корректно" явно не фигурировал.
Ты не знаешь, что там точно было.
Я не знаю, что там точно было.
Вот тебе вариант совершенно навскидку, но для меня выглядит правдоподобно: сначала код получал объём памяти через вызов B-1588. Тот отдаёт килобайты после 0x100000 в AX, соответственно, предел в 64MB (плюс 640KB). Они заточились чуть наперёд на то, что его можно расширить, например, до 256MB, если кто-то отрапортует новыми средствами, и соответственно рассчитали размеры таблиц. Потом кто-то другой в другом месте перевёл запрос доступной памяти на использование вызова B-15E801, который способен отдать к нему дополнительно "DX = configured memory above 16M, in 64K blocks", соответственно до 4GB, а код в построителе таблиц для пейджинга просто не обновили соответственно. Оно выдержало и 256MB, и много следующих размеров типа 384MB, но на 480MB стало падать.
В результате, проблема не техническая, а административная: если бы результаты второй правки были адекватно отрапортованы в первую, то проблемы бы не было. А использовать тотальный defensive programming между собственными микро-компонентами в пределах одной службы... как по мне, это избыточно в 99.99% случаев, толку нет.
Если возражаешь — покажи код. Я подозреваю, что код старта Windows 95 где-то давно утёк, только я, увы, в существующих утечках видел только сильно более поздние версии. Пока кода нет — обсуждать дальше нет смысла.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>С 480 Мб для Win 95 косяк был не в том, что выбрали фиксированный разумно достаточный размер пула, а то, что вместо игнорирования "лишней" памяти получился отказ в загрузке всей системы. Если и ставился вопрос "а вдруг памяти окажется до хренища?", то ответ "в таком случае надо выйти из ситуации корректно" явно не фигурировал.
Вряд ли такой дизайн был. Банальный баг, скорее. Ну в момент выхода системы, предназначенной для 386sx/4V, не пришло в голову тестить её с 480 Мб памяти. Если вообще в тот момент такую конфигурацию вообще можно было собрать, в чем я сомневаюсь
Re[10]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>В современных процессорах, как правило, деление на 0 или деление с переполнением не вызывает исключения
И это очень странно. Из каких соображений это делается?
N>RISC-V обещает, что беззнаковое деление на 0 даст ~0 (как UINT_MAX).
Такой подход ломает одно из основных свойств целочисленного деления (модуль частного не больше модулей делимого и делителя).
N>Язык может генерировать исключение на это или подставлять такой же безопасный дефолт.
В чем "безопасность" такого дефолта? Вот имеем байтовое смещение, делим на размер элемента, ожидаем получить индекс элемента. Вместо размера по ошибке делим на нуль, получаем UINT_MAX, применяем в качестве индекса. В соседней теме
смотрим, какая доля участников высказалась против автоматической вставки проверок индексов. Какую перспективу имеем?
N>Если исключение отражается в видимой диагностике, это можно было бы написать.
N>вообще подход, что не предполагается обрабатывать ошибки в арифметике, потому что нет возможности их отобразить в результате операции.
Почему нет? Или предусмотреть перехват возможного исключения, или проверить операнд(ы) перед выполнением операции.
N>Ты не знаешь, что там точно было.
Почему? Я точно знаю, что система переставала загружаться.
N>Я не знаю, что там точно было.
N>Потом кто-то другой в другом месте перевёл запрос доступной памяти на использование вызова B-15E801, который способен отдать к нему дополнительно "DX = configured memory above 16M, in 64K blocks", соответственно до 4GB, а код в построителе таблиц для пейджинга просто не обновили соответственно.
А можно было просто иметь одну функцию вроде GetMemorySize, которая определяет объем памяти любым удобным образом, тогда и части кода согласовывать не придется.
N>использовать тотальный defensive programming между собственными микро-компонентами в пределах одной службы... как по мне, это избыточно в 99.99% случаев, толку нет.
В ортогональности и унификации всегда есть толк.
Re[11]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>В современных процессорах, как правило, деление на 0 или деление с переполнением не вызывает исключения ЕМ>И это очень странно. Из каких соображений это делается?
We considered raising exceptions on integer divide by zero, with these exceptions causing a trap in most execution environments. However, this would be the only arithmetic trap in the standard ISA (floating-point exceptions set flags and write default values, but do not cause traps) and would require language implementors to interact with the execution environment’s trap handlers for this case. Further, where language standards mandate that a divide-by-zero exception must cause an immediate control flow change, only a single branch instruction needs to be added to each divide operation, and this branch instruction can be inserted after the divide and should normally be very predictably not taken, adding little runtime overhead.
The value of all bits set is returned for both unsigned and signed divide by zero to simplify the divider circuitry. The value of all 1s is both the natural value to return for unsigned divide, representing the largest unsigned number, and also the natural result for simple unsigned divider implementations. Signed division is often implemented using an unsigned division circuit and specifying the same overflow result simplifies the hardware.
N>>RISC-V обещает, что беззнаковое деление на 0 даст ~0 (как UINT_MAX). ЕМ>Такой подход ломает одно из основных свойств целочисленного деления (модуль частного не больше модулей делимого и делителя).
Попытка деления на 0 вообще бессмысленна в пределах целых чисел. Что именно возвращать в таком легко детектируемом случае — вопрос реализации. См. выше.
N>>Язык может генерировать исключение на это или подставлять такой же безопасный дефолт. ЕМ>В чем "безопасность" такого дефолта? Вот имеем байтовое смещение, делим на размер элемента, ожидаем получить индекс элемента. Вместо размера по ошибке делим на нуль, получаем UINT_MAX, применяем в качестве индекса. В соседней теме
смотрим, какая доля участников высказалась против автоматической вставки проверок индексов. Какую перспективу имеем?
Сейчас тебе точно так же ни C ни C++ ничего не гарантируют. А должны были по умолчанию генерировать исключение, если по разуму, а не по комитету или кто там рулит. Так что тут без разницы. А вот возможность лёгкой проверки на такую ситуацию одной командой достаточна для устранения проблемы там, где она реально может быть.
N>>Если исключение отражается в видимой диагностике, это можно было бы написать.
N>>вообще подход, что не предполагается обрабатывать ошибки в арифметике, потому что нет возможности их отобразить в результате операции.
ЕМ>Почему нет? Или предусмотреть перехват возможного исключения, или проверить операнд(ы) перед выполнением операции.
Ну покажи это в современном языке. Я вот хочу видеть что-то в духе C# c = (checked)(a+b); — контекстно и в самом языке. А вместо этого должен писать свои оболочки или использовать от какого-то странного вендора (Boost ещё лучший по свойствам, но API у этого модуля кошмарненький).
N>>Потом кто-то другой в другом месте перевёл запрос доступной памяти на использование вызова B-15E801, который способен отдать к нему дополнительно "DX = configured memory above 16M, in 64K blocks", соответственно до 4GB, а код в построителе таблиц для пейджинга просто не обновили соответственно.
ЕМ>А можно было просто иметь одну функцию вроде GetMemorySize, которая определяет объем памяти любым удобным образом, тогда и части кода согласовывать не придется.
Так она и была. И было установлено при написании кода VM, что она не даст значение выше 64MB.
(В рамках того же предполагаемого сценария)
N>>использовать тотальный defensive programming между собственными микро-компонентами в пределах одной службы... как по мне, это избыточно в 99.99% случаев, толку нет. ЕМ>В ортогональности и унификации всегда есть толк.
Здравствуйте, netch80, Вы писали:
N>Попытка деления на 0 вообще бессмысленна в пределах целых чисел. Что именно возвращать в таком легко детектируемом случае — вопрос реализации.
Я так и не понял, в чем смысл. Какая разница, что с чем сравнивать — частное с -1, или делитель с нулем?
А если они хотели избавить разработчиков языков от необходимости поддерживать системные механизмы обработки исключений, то они фактически предложили создавать реализации языков так, чтобы любое некорректное обращение к памяти сразу и наглухо валило всю программу, без возможности это обработать.
N>Сейчас тебе точно так же ни C ни C++ ничего не гарантируют.
И поэтому решили сделать очередной кривой костыль?
N>должны были по умолчанию генерировать исключение
Процессор его и генерирует. Вроде никогда не возникало сколько-нибудь значимых проблем с реализацией обработки.
N>Ну покажи это в современном языке. Я вот хочу видеть что-то в духе C# c = (checked)(a+b); — контекстно и в самом языке. А вместо этого должен писать свои оболочки или использовать от какого-то странного вендора
Эти вопросы задавайте разработчикам языков и их реализаций. Я сам уже лет тридцать, как в изумлении от того, насколько упорно не желают реализовать даже самые примитивные и дешевые средства, сильно упрощающие жизнь.
N>И было установлено при написании кода VM, что она не даст значение выше 64MB.
Так и ограничили бы принудительно прямо внутри функции — она и не давала бы никогда.
Re[13]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Попытка деления на 0 вообще бессмысленна в пределах целых чисел. Что именно возвращать в таком легко детектируемом случае — вопрос реализации. ЕМ>Я так и не понял, в чем смысл. Какая разница, что с чем сравнивать — частное с -1, или делитель с нулем?
Второе честнее.
ЕМ>А если они хотели избавить разработчиков языков от необходимости поддерживать системные механизмы обработки исключений,
Прочитайте ещё раз. Ну пожалуйста.
EM> то они фактически предложили создавать реализации языков так, чтобы любое некорректное обращение к памяти сразу и наглухо валило всю программу, без возможности это обработать.
Мне сложно себе представить, что в том, что я написал, могло быть прочитано с таким выводом.
N>>должны были по умолчанию генерировать исключение ЕМ>Процессор его и генерирует.
Уже нет (если мы про новые архитектуры).
N>>Ну покажи это в современном языке. Я вот хочу видеть что-то в духе C# c = (checked)(a+b); — контекстно и в самом языке. А вместо этого должен писать свои оболочки или использовать от какого-то странного вендора
ЕМ>Эти вопросы задавайте разработчикам языков и их реализаций. Я сам уже лет тридцать, как в изумлении от того, насколько упорно не желают реализовать даже самые примитивные и дешевые средства, сильно упрощающие жизнь.
Спасибо, вы очень помогли.
N>>И было установлено при написании кода VM, что она не даст значение выше 64MB. ЕМ>Так и ограничили бы принудительно прямо внутри функции — она и не давала бы никогда.
И снова не хотите читать написанное русским по фоновому.
The God is real, unless declared integer.
Re[14]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
ЕМ>>Какая разница, что с чем сравнивать — частное с -1, или делитель с нулем?
N>Второе честнее.
Тогда для чего здесь какие-то телодвижения со стороны разработчиков архитектуры? Сравнивать делитель с нулем — задача программиста или разработчика языка.
N>Прочитайте ещё раз.
Я до этого прочитал дважды. Давайте перечитаем в третий раз:
However, this ... would require language implementors to interact with the execution environment’s trap handlers for this case
Здесь написано, что разработчики архитектуры вроде бы заботятся о разработчиках языков, и отказ от формирования исключения вроде бы имеет целью избавить разработчиков языков от поддержки обработки аппаратных исключений.
Если я, по-Вашему, снова понял неправильно — попробуйте привести перевод, из которого следует что-то иное.
ЕМ>>Процессор его и генерирует.
N>Уже нет (если мы про новые архитектуры).
А при обращении по нулевому адресу генерирует? Если да, то для чего?
N>Спасибо, вы очень помогли.
Я мог бы помочь как-то иначе?
ЕМ>>Так и ограничили бы принудительно прямо внутри функции — она и не давала бы никогда.
N>И снова не хотите читать написанное русским по фоновому.
Скорее тупо не могу понять оправданий, выдаваемых за объяснения. Если бы Чен написал "в нашем коде была ошибка, из-за которой система переставала грузиться вместо того, чтобы просто игнорировать лишнюю память", то и возражений бы не было. Но он ведь не признал, что это был их косяк, оправдывая это маловероятностью. И Вы их оправдываете в том же ключе.
Re[15]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>>Какая разница, что с чем сравнивать — частное с -1, или делитель с нулем? N>>Второе честнее. ЕМ>Тогда для чего здесь какие-то телодвижения со стороны разработчиков архитектуры? Сравнивать делитель с нулем — задача программиста или разработчика языка.
Движения у них очень просты:
1. Решили, что ситуация некорректности операции деления не заслуживает того, чтобы (по крайней мере в базовом ISA) требовать для этого механизм исключений.
Можно было бы это списать на подход RISC-V, где явно декларируется метод "мы позволяем самые минимальные реализации, если кому-то нужно, и постепенное расширение", но ARM/64, который совсем не планировался компактным, делает то же самое. Значит, соображения у них примерно одного плана: оно не заслуживает настолько особой обработки.
2. Если команда не делает исключения, то надо вернуть какое-то осмысленное значение в качестве частного. Варианты — ближайшее к бесконечности с нужной стороны (лучше всего), просто ближайшее к бесконечности, ноль, что-то иное. ARM/64 выбрал ноль, и мне это решение кажется достаточно нелепым. В RISC-V посмотрели с вот какой стороны: простейший итерационный делитель в железе, returning или non-returning типа, на такое выдаст ответ из всех единичных битов, если специально не делать проверку на ноль. Ну, значит, его и потребуем. (Это может не расширяться на знаковое деление само по себе, но тут уже обобщили.)
N>>Прочитайте ещё раз.
ЕМ>Я до этого прочитал дважды. Давайте перечитаем в третий раз:
ЕМ>
ЕМ>However, this ... would require language implementors to interact with the execution environment’s trap handlers for this case
ЕМ>Здесь написано, что разработчики архитектуры вроде бы заботятся о разработчиках языков, и отказ от формирования исключения вроде бы имеет целью избавить разработчиков языков от поддержки обработки аппаратных исключений.
ЕМ>Если я, по-Вашему, снова понял неправильно — попробуйте привести перевод, из которого следует что-то иное.
Да, именно так. Если бы деление на ноль вызывало исключение, то для внедрителей языков была бы дополнительная забота взаимодействия со сложным механизмом (traps) вместо простого (одна проверочная команда там, где это нужно).
Что не так?
ЕМ>>>Процессор его и генерирует. N>>Уже нет (если мы про новые архитектуры). ЕМ>А при обращении по нулевому адресу генерирует? Если да, то для чего?
Зависит от системы защиты памяти. Обычно DAT настраивается так, что страница с адресом 0 недоступна для любого доступа по крайней мере для юзерленда. (Случай ядра — зависит от местной практики. Обычно полезно, да, перемапить её на что-то другое. Но могут и не делать.)
А какая связь? Сам по себе механизм защиты памяти уже системный и требует настройки.
N>>Спасибо, вы очень помогли. ЕМ>Я мог бы помочь как-то иначе?
Да, конструктивным рассмотрением вопросов дискуссии.
ЕМ>>>Так и ограничили бы принудительно прямо внутри функции — она и не давала бы никогда.
N>>И снова не хотите читать написанное русским по фоновому.
ЕМ>Скорее тупо не могу понять оправданий, выдаваемых за объяснения. Если бы Чен написал "в нашем коде была ошибка, из-за которой система переставала грузиться вместо того, чтобы просто игнорировать лишнюю память", то и возражений бы не было. Но он ведь не признал, что это был их косяк, оправдывая это маловероятностью. И Вы их оправдываете в том же ключе.
Это вы серьёзно — всё, что вы хотите, это чтобы Чен явно сказал "это была наша ошибка"? И если бы он сказал, вы бы вообще не подняли тему?
Тогда это как минимум оффтопик для данного подфорума. В чикаге было 100500 ошибок, недоделок, неоптимальных решений и прочего, и они постепенно правились — или не правились. Ни у кого нет бесконечного количества ресурсов на разработку и учёт всего. Результат оптимизируется под типовые пути работы, и часто различие лежит в том, этих типовых 1 или хотя бы 5. У хорошего разработчика 5. У отличного 10. У плохого 1, или 2, если начальство применило ключ достаточного размера для бития по башке.
Я не вижу смысла считать данную ситуацию какой-то существенной ошибкой потому, что оно не приводило к искажению данных, потере данных, неожиданной критической неработоспособности и т.п. — по крайней мере при нормальном админ. процессе у пользователя. Апгрейд железа или переход на новое это всегда особое событие, проверка на новом необходима перед переводом рабочей нагрузки на неё. Система не поддерживает какую-то не свойственную для её обычного профиля конфигурацию? Да таких профилей были реально тысячи! Масса нестандартного железа, и не только в сторону неожиданно хороших характеристик — как правило, это были локальные кривости всех видов.
А самое прямое для данной дискуссии — это что вы ввели тут уже сильно позже исходного сообщения какую-то необходимость извиняться, когда этого в вашем начальном сообщении не было и вы вместо этого обсуждали "уровень студента-второкурсника". Почему и зачем вы ввернули это только сейчас и походя, и теперь на этом основании чего-то требуете уже от меня?
Нехорошо, товарисч.
The God is real, unless declared integer.
Re[7]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Так они тоже не сами к этому пришли. Лучше переформулировать, что жрёт не браузер, а сайты в нём. ЕМ>Это вечная проблема перекладывания ответственности. "Наркоторговцы не виноваты — они лишь отвечают на возрастающий спрос, работайте с потребителями".
Сравнение вебостроителей с наркоторговцами — это, конечно, сильный полемический приём. Ценю. Но согласиться не могу.
N>>Я честно не думаю, что от замены JS на что-то другое, менее тупое, тут стало бы сильно легче. ЕМ>Сильно легче стало бы не от замены, а от изначального ограничения активности ваб-страницы чем-нибудь вроде расширенного CSS, где реализован разумный набор средств взаимодействия (те же спойлеры, деревья, простые реакции на действия пользователя и т.п.). Для подавляющего большинства информационных сайтов этого бы хватило, а кому надо интерактивности — делайте приложения, хоть нативные под ОС, хоть универсальные под единую VM, роль которой сейчас исполняют браузеры.
Ну вот и посмотрите теперь сами, что получается. Вы предлагаете некое разделение между "расширенным CSS" и "приложениями", которые могут при этом работать в такой же "единой VM". Тогда в чём разница, если любой автор приложения может легко получить реализацию того же в "единой VM", и не полагаться вообще на "расширенный CSS"?
Вы будете ставить ему платную границу?
JS тем и оказался хорош, что он _плавно_ внедряется в HTML+CSS среду. Можно не иметь ни единого скрипта. Можно 1-2 крошечных. Можно сделать снежинки и не трогать остальное (любимая фишка района 2000 на Новый год). На серверной стороне точно так же плавно въезжал PHP, на чём и получил популярность. А вы предлагаете рисовать какую-то искусственную границу.
Сейчас она по факту определяется тем, что пользователь закроет слишком толстый сайт — и таких будет какая-то доля процентов, чтобы определить "вот эта правка убила 3% пользователей, откатываем назад". И это нормально работает в подавляющем большинстве случаев.
ЕМ>Хреново ведь стало вовсе не от того, что появился JS, а от того, что его впихнули в заведомо неподходящее средство. Человеку нужно средство доступа к базовым сетевым сервисам, а в нагрузку он получает еще один компьютер.
Он просто получает использование средств своего компьютера. А проблема не в этом, а в том, что в отличие от ситуации "вот это приложение весит 2GB, я сознательно принял решение потратить этот объём своего диска на него" получается, что контроля за объёмами затраченных ресурсов нет, или ресурсы слишком быстро меняются, чтобы успевать за ними.
EM> То же самое случилось и с телефонами — человеку нужно средство связи, а в нагрузку он получает кучку средств доставки рекламы и привязки к поставщикам услуг.
Вопрос монетизации сервисов для "средства связи" (и не только связи — я вот перешёл на смартфон, когда мне потребовался навигатор) это другой вопрос и смешивать его с текущим уже нехорошо.
N>>веб тут в целом сам по себе болезнь ЕМ>Болезнь — не веб, а его превращение в балаган.
Мы примерно ровесники, мне кажется. И почему я не стал на такую, откровенно говоря, старперско-брюзгливую позицию?
The God is real, unless declared integer.
Re[16]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Решили, что ситуация некорректности операции деления не заслуживает того, чтобы (по крайней мере в базовом ISA) требовать для этого механизм исключений.
Если вопрос в том, чтобы вовсе не иметь в реализации механизма исключений, то это вполне разумно. Но тогда разумно ввести соответствующий флаг состояния, по аналогии с переполнением, а не возвращать результат, который, не будучи специально проверен, почти гарантированно наделает бед. Когда такое решение приходит в одну больную голову, это еще можно понять, но когда оно принимается коллегиально, это уже что-то запредельное.
Если же механизм исключений имеется, но решено отказаться от возбуждения исключения, то это непонятно вообще.
N>Можно было бы это списать на подход RISC-V, где явно декларируется метод "мы позволяем самые минимальные реализации, если кому-то нужно, и постепенное расширение", но ARM/64, который совсем не планировался компактным, делает то же самое. Значит, соображения у них примерно одного плана: оно не заслуживает настолько особой обработки.
N>Если команда не делает исключения, то надо вернуть какое-то осмысленное значение в качестве частного. Варианты — ближайшее к бесконечности с нужной стороны (лучше всего), просто ближайшее к бесконечности, ноль, что-то иное.
Значение, ближайшее к бесконечности, можно считать осмысленным только для деления с плавающей точкой. Для деления с фиксированной оно, наоборот, абсурдно.
N>ARM/64 выбрал ноль, и мне это решение кажется достаточно нелепым.
Мне тоже, Скорее уж единицу.
N>простейший итерационный делитель в железе, returning или non-returning типа, на такое выдаст ответ из всех единичных битов, если специально не делать проверку на ноль. Ну, значит, его и потребуем.
Если они стремятся экономить такты или логические связи, то именно в конкретной ситуации это тоже абсурдно.
N>Если бы деление на ноль вызывало исключение, то для внедрителей языков была бы дополнительная забота взаимодействия со сложным механизмом (traps) вместо простого (одна проверочная команда там, где это нужно).
И какова вероятность того, что в языке, реализованном для архитектуры, мало-мальски сложной (имеющей тот же диспетчер памяти), вообще не будут поддерживаться механизмы исключений?
Если уж они решили одновременно и упростить, и унифицировать, и оставить возможность масштабирования, то единственно правильное решение — это устанавливать флаг состояния. При наличии механизма исключений можно было бы добавить возбуждение исключения, как и для переполнения при умножении.
N>А какая связь? Сам по себе механизм защиты памяти уже системный и требует настройки.
Связь такая, что у программы должна быть возможность получать информацию о нештатных ситуациях при ее выполнении. Когда процессор эту информацию имеет, но не отдает, либо отдает в неадекватном виде, это требует экстраординарных оснований. Такие основания есть?
ЕМ>>Я мог бы помочь как-то иначе?
N>Да, конструктивным рассмотрением вопросов дискуссии.
И что конструктивного я мог бы сказать по поводу отсутствия в языках даже самых простых в реализации средств контроля исполнения? Я действительно не знаю, почему в индустрии преобладает стремление внедрять свистоперделки, порой достаточно дорогие в реализации, но упорно избегать внедрения дешевых и эффективных средств.
N>всё, что вы хотите, это чтобы Чен явно сказал "это была наша ошибка"? И если бы он сказал, вы бы вообще не подняли тему?
Да, именно так. Он высказался в стиле "у нас все было правильно, просто никто не ожидал". Я в подобной ситуации всегда признаю, что было-то ведь неправильно и ненадежно, но или не обратил внимания, или понадеялся на лучшее.
N>Тогда это как минимум оффтопик для данного подфорума.
Это был лишь очередной пример проблемы, к которой привел произвольный выбор фиксированной константы. И ведь того, что выбор константы в 2 Гб тоже был неудачным, они тоже не признают.
N>Ни у кого нет бесконечного количества ресурсов на разработку и учёт всего.
Да ладно бы такая ошибка была в сколько-нибудь объемном коде, с неочевидными зависимостями, которые трудно проследить в уме. Но в достаточно компактном коде загрузчика, который заполняет массив фиксированного размера, отсутствие адекватных действий при переполнении должно было насторожить.
N>вы ввели тут уже сильно позже исходного сообщения какую-то необходимость извиняться
Не извиняться, а признавать свои ошибки.
Re[8]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Вы предлагаете некое разделение между "расширенным CSS" и "приложениями", которые могут при этом работать в такой же "единой VM".
Верно.
N>Тогда в чём разница, если любой автор приложения может легко получить реализацию того же в "единой VM", и не полагаться вообще на "расширенный CSS"?
Разница достаточно большая. Во-первых, это позволило бы сохранить браузер именно в виде браузера (универсального инструмента для просмотра информации в сети), а не уродливого монстра, напоминающего текстовый процессор с прикрученными к нему позднее сбоку компилятором, отладчиком и дизассемблером. То есть, у любого пользователя был бы компактнй и безопасный инструмент для взаимодействия с информационной частью сети, а для коммерческо-развлекательной были бы отдельные инструменты.
Во-вторых, это умерило бы аппетиты сайтостроителей. В ситуации, когда у любого пользователя гарантированно есть средство для "разумно-активного" взаимодействия, но средства для "полноценного" (с точки зрения сайтостроителя) взаимодействия может не быть, многие предпочли бы ограничиться менее навороченным, но более доступным и надежным вариантом.
В-третьих, легкий и ненапряжный для пользователя переход по ссылке в браузере не создавал бы ему лишних рисков, а для установки приложения, пусть и универсального в единую подсистему ОС, уже требовалось бы явное разрешение.
N>JS тем и оказался хорош, что он _плавно_ внедряется в HTML+CSS среду.
А плох тем, что у этой плавности нет верхней границы. Уже давно подобрали хороший пример — это как пустить представителя организации, с которой нужно поддерживать отношения, жить к себе домой. Да, он может обещать вести себя хорошо, и он может быть наказан за нарушения, но доверять ему придется, как любому члену семьи.
И этот подход в итоге привел к фантастически уродливым решениям вроде запуска отдельных процессов, со специальными режимами защиты памяти, для обработки вкладок. То есть, дом, в котором изначально предполагались "все свои", теперь разгорожен на отсеки стенами повышенной прочности, в двери установлены замки повышенной надежности, но конца этому процессу не видно, он идет параллельно процессу развития любой ОС, создающей среду для разнородных приложений.
N>Сейчас она по факту определяется тем, что пользователь закроет слишком толстый сайт
Самое смешное, что толстый сайт с наибольшей вероятностью закроет пользователь, которому этот сайт не был бы нужен и тонким.
N>будет какая-то доля процентов, чтобы определить "вот эта правка убила 3% пользователей, откатываем назад".
Вы действительно верите, что нынче найдется хоть сколько-нибудь заметное количество людей, способных хотя бы на такой анализ, не говоря уже о возможности организовать откат?
ЕМ>>Человеку нужно средство доступа к базовым сетевым сервисам, а в нагрузку он получает еще один компьютер.
N>Он просто получает использование средств своего компьютера.
Да — через представителя, поселяемого дома. А они, как та лисичка — сперва лапку, потом другую...
N>в отличие от ситуации "вот это приложение весит 2GB, я сознательно принял решение потратить этот объём своего диска на него" получается, что контроля за объёмами затраченных ресурсов нет
Установленные приложения уже давно занимают ресурсы, даже близко не соответствующие заявленным. Вроде качаешь 50 Мб, а по факту оно занимает 300, и через короткое время откуда-то берет еще 200. Но так они хоть гадят в более-менее известные места ФС, а не в профиль браузера, где сам черт не разберется, и откуда их потом не выковырять без радикальных мер.
N>Мы примерно ровесники, мне кажется. И почему я не стал на такую, откровенно говоря, старперско-брюзгливую позицию?
Возможно, у Вас больше веры в разум человечества. У меня такая позиция была и в тридцать лет.
Re[17]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Решили, что ситуация некорректности операции деления не заслуживает того, чтобы (по крайней мере в базовом ISA) требовать для этого механизм исключений. ЕМ>Если вопрос в том, чтобы вовсе не иметь в реализации механизма исключений, то это вполне разумно. Но тогда разумно ввести соответствующий флаг состояния, по аналогии с переполнением, а не возвращать результат, который, не будучи специально проверен, почти гарантированно наделает бед. Когда такое решение приходит в одну больную голову, это еще можно понять, но когда оно принимается коллегиально, это уже что-то запредельное.
Что вы решили назвать тут флагом состояния?
Вот, например, самая первая операция, которую рассматривают — сложение. Пусть у нас байтовые параметры. Сложив 0x01 и 0xFF, мы получаем 0x00. Но в знаковой интерпретации это нормально, а в беззнаковой это переполнение. Мы должны детектировать это переполнение? Если да, как выглядит этот "флаг состояния"?
Архитектура типа RISC-V намеренно лишена аналога Flags в x86. Даже не как в ARM, где у большинства команд этой группы можно управлять, есть там флаги или нет. Не знаю, насколько правильно в самом глобальном смысле это решение само по себе. Но если оно сделано, то явная проверка требуется не только на деление. Сложение, вычитание, умножение — они все требуют проверок на валидность результата, не был ли он усечён (после чего об его корректности вообще нет смысла говорить, лучше считать тупо мусором). В чём особенность тут одного деления по сравнению с остальными?
Пусть у нас теперь есть Flags в варианте, например, как в x86. Все операции ставят флаги. Мы можем добавлять JO или INTO после команды. Мы можем добавлять JC. Вопрос: почему нет парной к ней INTC?
(Да, я буду регулярно сравнивать с x86. Это "а у вас негров линчуют", я заранее согласен.)
Есть один вариант решения: флагов нет, ставьте явные проверки по диапазонам и конкретным значениям, где нужно. Есть другой: флаги есть, можно реагировать на них. Тут уже вопрос, кто и что как ставит. Я бы не против, если б SDIV ставила OF (как бы они ни звались) в случаях деления на 0 или MIN/-1. Но вводить ещё и фолт для одного-единственного случая — точно явный и неуместный перекос. Когда это сделали в S/360, там было понятно — откровенно пионерная архитектура. Когда это сделали в 8086 через 14 лет — зачем это было? Неужели не было уже понятно по опыту развития, что в этом нет смысла?
Кстати, я ни в одной архитектуре кроме POWER не видел "накопительного" флага переполнения, и то там есть такой только для знакового. А обычные надо проверять после каждой операции.
ЕМ>Если же механизм исключений имеется, но решено отказаться от возбуждения исключения, то это непонятно вообще.
Механизм появляется вместе с более высокими уровнями реализации (в RISC-V). Но его принудительная ориентация на обработку в супервизоре избыточна.
N>>Если команда не делает исключения, то надо вернуть какое-то осмысленное значение в качестве частного. Варианты — ближайшее к бесконечности с нужной стороны (лучше всего), просто ближайшее к бесконечности, ноль, что-то иное.
ЕМ>Значение, ближайшее к бесконечности, можно считать осмысленным только для деления с плавающей точкой. Для деления с фиксированной оно, наоборот, абсурдно.
И опять же. Сложили 0x01 и 0xFF в беззнаковом контексте, получили 0 вместо 0x100. Не заметили, пошли дальше, нарвались на что-то и приветъ. Будем трапаться на таком или нет? Я согласен только на универсальный подход, потому что в упор не вижу, чем деление тут должно быть таким особенным.
N>>Если бы деление на ноль вызывало исключение, то для внедрителей языков была бы дополнительная забота взаимодействия со сложным механизмом (traps) вместо простого (одна проверочная команда там, где это нужно). ЕМ>И какова вероятность того, что в языке, реализованном для архитектуры, мало-мальски сложной (имеющей тот же диспетчер памяти), вообще не будут поддерживаться механизмы исключений?
Да вообще-то на таком уровне ровно 100%. В C нет никаких исключений. Если где-то вы видите, например, обработчик SIGFPE (в который по POSIX мапится деление на 0, если трапается), то в нём всё равно нельзя без платформенно-специфичных средств вернуться на ту же команду. Максимум это через siglongjmp() вернуться на какую-то заранее придуманную контрольную точку. Если речь про Windows, то SEH это тоже не элемент языка, а расширение для конкретной платформы.
ЕМ>Если уж они решили одновременно и упростить, и унифицировать, и оставить возможность масштабирования, то единственно правильное решение — это устанавливать флаг состояния. При наличии механизма исключений можно было бы добавить возбуждение исключения, как и для переполнения при умножении.
Да, такое определено в IEEE754. Там накопительные флаги и возможность управления ими. А теперь покажите мне такое в x86 или SystemZ (где деление на 0 трапается) такие накопительные флаги?
N>>А какая связь? Сам по себе механизм защиты памяти уже системный и требует настройки. ЕМ>Связь такая, что у программы должна быть возможность получать информацию о нештатных ситуациях при ее выполнении. Когда процессор эту информацию имеет, но не отдает, либо отдает в неадекватном виде, это требует экстраординарных оснований. Такие основания есть?
Отлично, жду ваших оснований для отсутствия накопительных флагов переполнения в x86.
ЕМ>И что конструктивного я мог бы сказать по поводу отсутствия в языках даже самых простых в реализации средств контроля исполнения? Я действительно не знаю, почему в индустрии преобладает стремление внедрять свистоперделки, порой достаточно дорогие в реализации, но упорно избегать внедрения дешевых и эффективных средств.
В языках-то оно есть. Возьмите какую-нибудь Ada и там всё будет под полным контролем.
N>>всё, что вы хотите, это чтобы Чен явно сказал "это была наша ошибка"? И если бы он сказал, вы бы вообще не подняли тему? ЕМ>Да, именно так. Он высказался в стиле "у нас все было правильно, просто никто не ожидал".
Не вижу в его словах такого акцента.
N>>Тогда это как минимум оффтопик для данного подфорума. ЕМ>Это был лишь очередной пример проблемы, к которой привел произвольный выбор фиксированной константы.
Лучше бы вспомнили историю ATA геометрий — она красочнее. В общем же случае я думаю, что каждое расширение какого-то реального параметра в 2-3 раза приводит к наступанию на очередной предел.
EM> И ведь того, что выбор константы в 2 Гб тоже был неудачным, они тоже не признают.
Он был 99.99% удачен. Остальных давно ждал 64-битный режим. На это я уже отвечал.
N>>Ни у кого нет бесконечного количества ресурсов на разработку и учёт всего.
ЕМ>Да ладно бы такая ошибка была в сколько-нибудь объемном коде, с неочевидными зависимостями, которые трудно проследить в уме. Но в достаточно компактном коде загрузчика, который заполняет массив фиксированного размера, отсутствие адекватных действий при переполнении должно было насторожить.
Тогда на всём экономили.
Вон загрузчик MS-DOS где-то аж до версии 5 должен был получать io.sys первым в корневом каталоге, иначе беда. А всё потому, что решили, что нефиг в FAT даже на винче выдать десяток секторов на более умный промежуточный читатель FS. В котором из FAT это стало обязательным? Чуть ли не в 32м.
Про саму проблему трёх областей видимости (20, 32 и 64 бита адреса) уже и не вспоминаю, там и сейчас есть где плясать часами на костях.
N>>вы ввели тут уже сильно позже исходного сообщения какую-то необходимость извиняться ЕМ>Не извиняться, а признавать свои ошибки.
Этому вообще весь блог посвящён в целом. "Old new thing" — о древностях, замшелостях и откуда они такие растут. Каждая из них это какая-то ошибка, отсталость, влияние древнего ограничения или просто недосмотр.
Это не требуется прописывать каждый раз.
The God is real, unless declared integer.
Re[9]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Тогда в чём разница, если любой автор приложения может легко получить реализацию того же в "единой VM", и не полагаться вообще на "расширенный CSS"?
ЕМ>Разница достаточно большая. Во-первых, это позволило бы сохранить браузер именно в виде браузера (универсального инструмента для просмотра информации в сети), а не уродливого монстра, напоминающего текстовый процессор с прикрученными к нему позднее сбоку компилятором, отладчиком и дизассемблером. То есть, у любого пользователя был бы компактнй и безопасный инструмент для взаимодействия с информационной частью сети, а для коммерческо-развлекательной были бы отдельные инструменты.
"Информационная" часть сети может и часто должна пользоваться теми же механизмами. На этом уровне их невозможно различить.
ЕМ>Во-вторых, это умерило бы аппетиты сайтостроителей. В ситуации, когда у любого пользователя гарантированно есть средство для "разумно-активного" взаимодействия, но средства для "полноценного" (с точки зрения сайтостроителя) взаимодействия может не быть, многие предпочли бы ограничиться менее навороченным, но более доступным и надежным вариантом.
Это было типовым в период, условно говоря, 1995-2005. Тогда было легче встретить сайт, который без JS работал на 99%, только без некоторых фишек, чем наоборот.
И тем не менее это закончилось. Сейчас мы имеем противоположную обстановку. И причина — таки желания пользователей, чтобы у них была одна платформа — браузер — для всего, иначе просто лень.
N>>JS тем и оказался хорош, что он _плавно_ внедряется в HTML+CSS среду. ЕМ>А плох тем, что у этой плавности нет верхней границы.
Да.
EM> Уже давно подобрали хороший пример — это как пустить представителя организации, с которой нужно поддерживать отношения, жить к себе домой. Да, он может обещать вести себя хорошо, и он может быть наказан за нарушения, но доверять ему придется, как любому члену семьи.
ЕМ>И этот подход в итоге привел к фантастически уродливым решениям вроде запуска отдельных процессов, со специальными режимами защиты памяти, для обработки вкладок. То есть, дом, в котором изначально предполагались "все свои", теперь разгорожен на отсеки стенами повышенной прочности, в двери установлены замки повышенной надежности, но конца этому процессу не видно, он идет параллельно процессу развития любой ОС, создающей среду для разнородных приложений.
Это все понимают, вы тут реально кэпствуете. Но альтернативы не видят. В отдельные приложения сейчас больше идёт то, что в браузере непригодно.
N>>будет какая-то доля процентов, чтобы определить "вот эта правка убила 3% пользователей, откатываем назад". ЕМ>Вы действительно верите, что нынче найдется хоть сколько-нибудь заметное количество людей, способных хотя бы на такой анализ, не говоря уже о возможности организовать откат?
Типовое умение в конторе больше условных 5 человек.
ЕМ>>>Человеку нужно средство доступа к базовым сетевым сервисам, а в нагрузку он получает еще один компьютер. N>>Он просто получает использование средств своего компьютера. ЕМ>Да — через представителя, поселяемого дома. А они, как та лисичка — сперва лапку, потом другую...
Ну пока что дальше браузера дело не идёт. Даже Microsoft со своим тем что развилось из Active Desktop, или Electron — просто используют механизмы браузера для своих задач.
N>>Мы примерно ровесники, мне кажется. И почему я не стал на такую, откровенно говоря, старперско-брюзгливую позицию? ЕМ>Возможно, у Вас больше веры в разум человечества. У меня такая позиция была и в тридцать лет.
Веры в "разум человечества" у меня нет. Просто я, наверно, лучше представляю себе, что происходит от тупизны, условно говоря, самих программистов, а что — от неизбежного следования запросам пользователей.
The God is real, unless declared integer.
Re[18]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Что вы решили назвать тут флагом состояния?
Классический флаг состояния процессора, используемый с незапамятных времен.
N>в знаковой интерпретации это нормально, а в беззнаковой это переполнение. Мы должны детектировать это переполнение?
Если у процессора в ходе выполнения программы возникает любая информация, которая с высокой вероятностью будет полезна этой программе, то да. Именно это и делает тот же x86 с флагами CF/OF, детектируя сразу обе ситуации.
N>Архитектура типа RISC-V намеренно лишена аналога Flags в x86.
И как, этим она существенно выигрывает у архитектур, где флаги есть?
N>Сложение, вычитание, умножение — они все требуют проверок
Именно так. Реализация этих проверок в топологии/микрокоде процессора всегда дешевле, чем в каждой из выполняемых на нем программ.
N>Мы можем добавлять JO или INTO после команды. Мы можем добавлять JC. Вопрос: почему нет парной к ней INTC?
Потому, что перенос очень часто является следствием нормального выполнения, и как-то специально его обрабатывать не требуется, а знаковое переполнение в большинстве случаев является нештатной ситуацией. Но флаги-то есть, и любое сочетание всегда можно обработать с ничтожными затратами.
N>Есть один вариант решения: флагов нет, ставьте явные проверки по диапазонам и конкретным значениям, где нужно.
Это откровенно убогий вариант, как и возврат из функции единственного результата, некоторые значения которого резервируются под коды ошибок. Оправдывается только в случае крайней экономии ресурсов.
N>Я бы не против, если б SDIV ставила OF (как бы они ни звались) в случаях деления на 0 или MIN/-1.
Это было бы следуюшим по разумности вариантом при отказе от исключения.
N>вводить ещё и фолт для одного-единственного случая — точно явный и неуместный перекос.
Почему, если механизм исключений уже поддерживается аппаратурой? Порождать исключения для арифметических переполнений нет смысла, поскольку они очень часто возникают в совершенно нормальных, запланированных ситуациях. А вот в какой нормальной, запланированной ситуации могло бы возникнуть деление на нуль, результат которого можно было бы далее использовать без проверки?
Это ж, по сути, то же самое, для чего вводились исключения в C++ — чтобы в ситуации, когда что-то пошло не так, не было риска забыть проверить возвращаемое значение в ситуации, когда не существует заведомо безопасного значения для нештатной ситуации.
N>Неужели не было уже понятно по опыту развития, что в этом нет смысла?
Тогда и в плюсовых исключениях тоже нет смысла. Не в их неправильном использовании, а в механизме, как твковом.
ЕМ>>Если же механизм исключений имеется, но решено отказаться от возбуждения исключения
N>Механизм появляется вместе с более высокими уровнями реализации (в RISC-V). Но его принудительная ориентация на обработку в супервизоре избыточна.
Если команда деления может присутствовать в архитектуре, не поддерживающей обработку исключений, или возбуждение исключения может быть запрещено, то наиболее разумным решением будет использование флага состояния.
N>Сложили 0x01 и 0xFF в беззнаковом контексте, получили 0 вместо 0x100. Не заметили, пошли дальше, нарвались на что-то и приветъ.
Да, возможность нарваться есть. Но она есть наравне с возможностью использовать это поведение для реализации естественных действий — тех же операций по модулю. А вот какие естественные операции могли бы выполняться командой целочисленного деления, возвращающей максимально возможное значение при нулевом делителе?
N>В C нет никаких исключений.
C — не язык "в себе". В C изначально закладывались на то, что исключения, если они есть в архитектуре, поддерживаются средой исполнения.
N>Если где-то вы видите, например, обработчик SIGFPE (в который по POSIX мапится деление на 0, если трапается), то в нём всё равно нельзя без платформенно-специфичных средств вернуться на ту же команду.
Возможность вернуться и повторить — это уже определенная роскошь. Основной является возможность реагировать на нештатную ситуацию без явных проверок.
N>покажите мне такое в x86 или SystemZ (где деление на 0 трапается) такие накопительные флаги?
Зачем нужны непременно накопительные? Как часто в них возникает потребность?
N>В языках-то оно есть. Возьмите какую-нибудь Ada и там всё будет под полным контролем.
А какой ценой?
N>Лучше бы вспомнили историю ATA геометрий — она красочнее.
Там были хоть какие-то объективные основания — разрядности шин, регистров, стоимость тогдашних микросхем и т.п.
N>В общем же случае я думаю, что каждое расширение какого-то реального параметра в 2-3 раза приводит к наступанию на очередной предел.
Это как раз понятно. Непонятно стремление вводить константы вместо переменных, хотя в основе математики лежала противоположная идея.
EM>>выбор константы в 2 Гб тоже был неудачным
N>Он был 99.99% удачен. Остальных давно ждал 64-битный режим
Тогда выбор одного гигабайта вместо двух был бы "удачным на 99.95%". А выбор 512 Мб — "на 99.9%". А фишка в том, что увеличение этой вероятности до максимальной не стоило бы практически ничего, но в итоге цена получилась вполне ощутимой.
N>Тогда на всём экономили.
В загрузчиках MBR/VBR — да. В загрузчике Win95 не было ни малейших причин экономить байты и такты.
Re[19]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Что вы решили назвать тут флагом состояния? ЕМ>Классический флаг состояния процессора, используемый с незапамятных времен.
Нет такого общего понятия. Есть много разных флагов, каждый со своим поведением.
N>>в знаковой интерпретации это нормально, а в беззнаковой это переполнение. Мы должны детектировать это переполнение? ЕМ>Если у процессора в ходе выполнения программы возникает любая информация, которая с высокой вероятностью будет полезна этой программе, то да. Именно это и делает тот же x86 с флагами CF/OF, детектируя сразу обе ситуации.
Тему с накопительным поведением вы проигнорировали.
N>>Архитектура типа RISC-V намеренно лишена аналога Flags в x86. ЕМ>И как, этим она существенно выигрывает у архитектур, где флаги есть?
Авторы считают, что отсутствие зависимости по скрытому значению — да, помогает в реализации. И она не одна такая. Вон MIPS ещё как минимум.
А теперь бинго — у x86 то же самое в векторных операциях... потому что не может быть одного флага результата на 4-8-16 разных операций впараллель
N>>Сложение, вычитание, умножение — они все требуют проверок ЕМ>Именно так. Реализация этих проверок в топологии/микрокоде процессора всегда дешевле, чем в каждой из выполняемых на нем программ.
Ну и где они в x86?
N>>Мы можем добавлять JO или INTO после команды. Мы можем добавлять JC. Вопрос: почему нет парной к ней INTC? ЕМ>Потому, что перенос очень часто является следствием нормального выполнения, и как-то специально его обрабатывать не требуется,
Нет здесь такой несимметричности.
N>>Есть один вариант решения: флагов нет, ставьте явные проверки по диапазонам и конкретным значениям, где нужно. ЕМ>Это откровенно убогий вариант, как и возврат из функции единственного результата, некоторые значения которого резервируются под коды ошибок. Оправдывается только в случае крайней экономии ресурсов.
Ну где говорят про экономию ресурсов, а где про резкое облегчение дизайна за счёт отсутствия единого регистра флагов и за счёт этого лучшую параллельность.
Заметьте, Intel в своём проекте APX намеревается сделать то же самое.
N>>Я бы не против, если б SDIV ставила OF (как бы они ни звались) в случаях деления на 0 или MIN/-1. ЕМ>Это было бы следуюшим по разумности вариантом при отказе от исключения.
Как раз более разумно, чем исключение
N>>вводить ещё и фолт для одного-единственного случая — точно явный и неуместный перекос. ЕМ>Почему, если механизм исключений уже поддерживается аппаратурой? EM> Порождать исключения для арифметических переполнений нет смысла, поскольку они очень часто возникают в совершенно нормальных, запланированных ситуациях.
Кажется, единственный вариант, при котором это возможно, это арифметика "по модулю". Назвать такое "очень часто" — это слишком сильная натяжка. От общего количества разных операций такого минимум и сконцентрированы они в некоторых совершенно конкретных областях: длинная арифметика, операции с кольцевыми счётчиками вроде seqnum в сетевых протоколах. А вот в, не побоюсь, 99% остальных если и кажется, что они есть, то это такие, в которых значение после переполнения проверяется на его выход за пределы ожидаемого множества. Например, в недавней дискуссии о роли беззнаковых — переход 0 -> ~0. А если не проверяется, а переполнение возможно, то код просто некорректен.
Уточню: я имею в виду вариант, когда тип значения обозначен. CF=1 при беззнаковом или OF=1 при знаковом.
EM> А вот в какой нормальной, запланированной ситуации могло бы возникнуть деление на нуль, результат которого можно было бы далее использовать без проверки?
Раз мы знаем, что "нормальных, запланированных" ситуаций с переполнениями почти нет, то уже нет тут никаких особых свойств деления. Некорректные входные данные дают некорректный результат, и если он распространяется на дальнейшую работу, то важно то, насколько рано (в идеале — сразу) ситуация поймана и опознана.
ЕМ>Это ж, по сути, то же самое, для чего вводились исключения в C++ — чтобы в ситуации, когда что-то пошло не так, не было риска забыть проверить возвращаемое значение в ситуации, когда не существует заведомо безопасного значения для нештатной ситуации.
Ну и почему на это плюют во всяких x86 для трёх операций из четырёх (это ещё и если не считать сдвиги за арифметику со степенью двойки, тогда окажется, что в 7 из 8)?
N>>Неужели не было уже понятно по опыту развития, что в этом нет смысла? ЕМ>Тогда и в плюсовых исключениях тоже нет смысла. Не в их неправильном использовании, а в механизме, как твковом.
Передёргиваете. Я ясно сказал, что возможность проверки есть и там, где её применяют, проблема детектируется. Может, чуть заморочно.
ЕМ>>>Если же механизм исключений имеется, но решено отказаться от возбуждения исключения N>>Механизм появляется вместе с более высокими уровнями реализации (в RISC-V). Но его принудительная ориентация на обработку в супервизоре избыточна. ЕМ>Если команда деления может присутствовать в архитектуре, не поддерживающей обработку исключений, или возбуждение исключения может быть запрещено, то наиболее разумным решением будет использование флага состояния.
Да. Если он есть.
ЕМ>C — не язык "в себе". В C изначально закладывались на то, что исключения, если они есть в архитектуре, поддерживаются средой исполнения.
Ну предположим.
N>>Если где-то вы видите, например, обработчик SIGFPE (в который по POSIX мапится деление на 0, если трапается), то в нём всё равно нельзя без платформенно-специфичных средств вернуться на ту же команду. ЕМ>Возможность вернуться и повторить — это уже определенная роскошь. Основной является возможность реагировать на нештатную ситуацию без явных проверок.
Тогда её нет с x86 для всего кроме деления — а там оно нужно сильно чаще, чем для деления.
Ситуацию незамеченного деления на 0 за весь свой опыт я видел только одну, а случаи проблем из-за непойманного переполнения при остальных трёх арифметических операциях — уже десятки.
N>>В языках-то оно есть. Возьмите какую-нибудь Ada и там всё будет под полным контролем. ЕМ>А какой ценой?
Проверка каждого результата при укладке в целевую переменную, на её границы, плюс операций с базовым размером значения (как int и long в C) на переполнения. Не сильно большая цена за реальную безопасность.
N>>Лучше бы вспомнили историю ATA геометрий — она красочнее. ЕМ>Там были хоть какие-то объективные основания — разрядности шин, регистров, стоимость тогдашних микросхем и т.п.
Все эти "разрядности" и "стоимости" это фактор ровно того же плана: суммарная цена решения.
N>>В общем же случае я думаю, что каждое расширение какого-то реального параметра в 2-3 раза приводит к наступанию на очередной предел. ЕМ>Это как раз понятно. Непонятно стремление вводить константы вместо переменных, хотя в основе математики лежала противоположная идея.
Ну вот вы почему-то постановили, что константы разрядности в виде 32 и 64 они оправданны, а остальные — нет. А я могу вспомнить жалобы при переходе на S/360, что 32-битный float был заметно хуже 36-битного по свойствам. Последствия этого убрали только в IEEE754, и то по мнению некоторых недостаточно качественно. Надо было таки оставить разрядности типа 36 и 72?
EM>>>выбор константы в 2 Гб тоже был неудачным N>>Он был 99.99% удачен. Остальных давно ждал 64-битный режим ЕМ>Тогда выбор одного гигабайта вместо двух был бы "удачным на 99.95%". А выбор 512 Мб — "на 99.9%". А фишка в том, что увеличение этой вероятности до максимальной не стоило бы практически ничего, но в итоге цена получилась вполне ощутимой.
В том и дело, что увеличение выше 2GB реально стоило — мороки программистам и производительности ядру. Сплошная перекачка данных между буферами.
N>>Тогда на всём экономили. ЕМ>В загрузчиках MBR/VBR — да. В загрузчике Win95 не было ни малейших причин экономить байты и такты.
Я уже ответил, что считаю, что причина в несогласовании между сотрудниками (отделами), а не в намеренной чрезмерной экономии.
The God is real, unless declared integer.
Re[20]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, netch80, Вы писали:
N>Тему с накопительным поведением вы проигнорировали.
Я задал вопрос: "Зачем нужны непременно накопительные? Как часто в них возникает потребность?". Вы не ответили.
N>Авторы считают, что отсутствие зависимости по скрытому значению — да, помогает в реализации.
В каком смысле это значение более "скрыто", нежели значения регистров или ячеек памяти? По состояниям отдельных флагов можно выполнить переход, их можно использовать в операциях, можно прочитать явно.
N>у x86 то же самое в векторных операциях... потому что не может быть одного флага результата на 4-8-16 разных операций впараллель
Насколько часто при векторных операциях необходимы ветвления по промежуточным результатам? Там, как правило, безусловные, "пакетные" алгоритмы.
ЕМ>>Реализация этих проверок в топологии/микрокоде процессора всегда дешевле, чем в каждой из выполняемых на нем программ.
N>Ну и где они в x86?
Во флагах состояния, вестимо. Пусть и не все, хотелось бы больше.
ЕМ>>Потому, что перенос очень часто является следствием нормального выполнения, и как-то специально его обрабатывать не требуется,
N>Нет здесь такой несимметричности.
Если сейчас навскидку скачать любой бинарник и дизассемблировать его — уверены, что действий со знаковыми величинами, при которых штатно возникает переполнение, найдем примерно столько же, сколько и для беззнаковых?
N>где говорят про экономию ресурсов
Экономия на флагах состояния на фоне сложности любого процессора даже 30-40-летней давности — это фикция, тех ресурсов там совершенно ничтожное количество, исчисляемое единицами логических элементов.
N>где про резкое облегчение дизайна за счёт отсутствия единого регистра флагов и за счёт этого лучшую параллельность.
Тоже непонятно, где здесь может быть "резкое облегчение". Параллельное выполнение даже простых арифметических операций требует наличия нескольких полноценных АЛУ, а флаги состояния из такого АЛУ выходят либо сами по себе, либо путем добавления единиц логических элементов. Некоторое упрощение получить можно, "резкое" — тупо неоткуда.
N>Заметьте, Intel в своём проекте APX намеревается сделать то же самое.
В последнее время явно видна тенденция сращивания функций процессора и компилятора. Если существующие архитектуры еще предполагали написание программы человеком на ассемблере, то новые уже предполагают только машинную генерацию кода. В таких условиях разумно целиком оптимизировать связку "компилятор+процессор" — возможно, в ней флаги состояния действительно получаются избыточными.
Но и x86, и ARM проектировались во времена, когда написание кода человеком на ассемблере использовалось достаточно широко.
ЕМ>>Это было бы следуюшим по разумности вариантом при отказе от исключения.
N>Как раз более разумно, чем исключение
Если предполагается, что программа всегда будет генерироваться автоматически, и статистика показывает, что затраты на проверку после каждого деления потеряются на общем фоне, то да.
EM>> Порождать исключения для арифметических переполнений нет смысла, поскольку они очень часто возникают в совершенно нормальных, запланированных ситуациях.
N>Кажется, единственный вариант, при котором это возможно, это арифметика "по модулю". Назвать такое "очень часто" — это слишком сильная натяжка.
Например, там, где нуль/ненуль нужно преобразовать в 0/1 или 0/-1, компиляторы вовсю используют комбинации из neg, sbb, inc и and. А счетчики с переполнением часто используются для отслеживания небольших временнЫх интервалов в алгоритмах реального времени.
N>мы знаем, что "нормальных, запланированных" ситуаций с переполнениями почти нет
Хорошо Вам, что "вы знаете". Я вот их использую регулярно, и столь же регулярно вижу в коде, который делает компилятор (те же преобразования int в bool). А вот операций с заведомо знаковыми величинами, при которых знаковое же переполнение было бы штатной ситуацией, и не требовало специальных действий, я с ходу даже не припомню, как и в случае деления на нуль.
ЕМ>>чтобы в ситуации, когда что-то пошло не так, не было риска забыть проверить возвращаемое значение в ситуации, когда не существует заведомо безопасного значения для нештатной ситуации.
N>Ну и почему на это плюют во всяких x86 для трёх операций из четырёх (это ещё и если не считать сдвиги за арифметику со степенью двойки, тогда окажется, что в 7 из 8)?
Где можно найти примеров, в которых это "наплевательство" требуется обставлять ловушками?
ЕМ>>Тогда и в плюсовых исключениях тоже нет смысла. Не в их неправильном использовании, а в механизме, как твковом.
N>Передёргиваете. Я ясно сказал, что возможность проверки есть и там, где её применяют, проблема детектируется. Может, чуть заморочно.
Пытаюсь увидеть разницу, но не вижу. Если в процессоре не возбуждать исключения при делении на нуль, а возвращать специальное значение, необходимо добавлять проверку после каждого деления; случаев, когда программа может безопасно использовать специальное значение, найдется очень мало. В C++ тоже можно обойтись без исключений, возвращая специальное значение, и тоже далеко не всегда его можно подобрать так, чтобы продолжение без проверки было безопасным. Разницу вижу только в том, что код для процессора сейчас преимущественно делает компилятор, который не забудет добавить проверку, а программы на C++ преимущественно делает человек, который может забыть.
N>Ситуацию незамеченного деления на 0 за весь свой опыт я видел только одну
Удивлен. Уж насколько я всегда избегал математики в своих программах, но у меня и делений хватает, и случаев ошибочного деления на нуль было предостаточно. Если б они не порождали исключений, и компилятор не спасал бы автоматической проверкой, я бы вздернулся их все разыскивать.
N>случаи проблем из-за непойманного переполнения при остальных трёх арифметических операциях — уже десятки.
Этих тоже хватало. Но, если б каждое такое переполнение порождало исключение, было бы еще хуже.
N>Проверка каждого результата при укладке в целевую переменную, на её границы, плюс операций с базовым размером значения (как int и long в C) на переполнения. Не сильно большая цена за реальную безопасность.
Это было бы полезно во всех без исключения языках, но не безусловно, а при возможности независимого управления каждым видом проверок.
N>Ну вот вы почему-то постановили, что константы разрядности в виде 32 и 64 они оправданны, а остальные — нет.
Это не "мы постановили", это непосредственно вытекает из физических, железных характеристик архитектуры. А числа вроде 2 Гб для границы АП, или 480 Мб для бессбойной загрузки Win95, ниоткуда не вытекают, а возникают произвольно.
N>жалобы при переходе на S/360, что 32-битный float был заметно хуже 36-битного по свойствам.
Вроде неудивительно. Чем не устраивал 64-битный?
N>Надо было таки оставить разрядности типа 36 и 72?
Они и так оставались доступными через 64- и 128-разрядные. Или Вы о хранении чисел в памяти?
N>увеличение выше 2GB реально стоило — мороки программистам и производительности ядру. Сплошная перекачка данных между буферами.
Почему при границе в 2 Гб "сплошной перекачки" нет, а при смещении на те же 3 Гб вдруг потребовалась?
Re[21]: Откуда такая неизбывная приверженность к константам?
Здравствуйте, Евгений Музыченко, Вы писали:
N>>Тему с накопительным поведением вы проигнорировали. ЕМ>Я задал вопрос: "Зачем нужны непременно накопительные? Как часто в них возникает потребность?". Вы не ответили.
На примере IEEE754 мы видим, как именно они нужны. Не проверять после каждой операции, а проверять после группы операций. Так как?
N>>Авторы считают, что отсутствие зависимости по скрытому значению — да, помогает в реализации. ЕМ>В каком смысле это значение более "скрыто", нежели значения регистров или ячеек памяти?
В том, что не названо явно в команде, но присутствует в ряде команд. Причём в вариантах x86, PDP-11, VAX, M68k и пачки других — неустранимо. ARM позволяет у большинства команд их не менять, и это уже большой прогресс.
(У тех архитектур ещё и во времена до тотального OoO любили ставить правило, что команда те флажки, которые ей не нужно ставить согласно логике, жёстко объявлены неизменными. А это и значит зависимость от предыдущего значения — то, от чего при OoO стараются уйти.
N>>у x86 то же самое в векторных операциях... потому что не может быть одного флага результата на 4-8-16 разных операций впараллель ЕМ>Насколько часто при векторных операциях необходимы ветвления по промежуточным результатам? Там, как правило, безусловные, "пакетные" алгоритмы.
А вы посмотрите, как их укладывают в этом случае. Часто приводят пример с операцией типа r[j] = (a[j] > b[j]) ? c[j] : d[j] в цикле; это, конечно, пример искусственный настолько же, насколько вычисление чисел Фибоначчи, но именно этим и показателен. В реале часто встречаются менее жёсткие версии, но всё же где надо делать развилки. Я получал лично такое в своём коде, когда векторизовывался какой-нибудь проход по тексту с поиском конкретных символов.
ЕМ>>>Реализация этих проверок в топологии/микрокоде процессора всегда дешевле, чем в каждой из выполняемых на нем программ. N>>Ну и где они в x86? ЕМ>Во флагах состояния, вестимо. Пусть и не все, хотелось бы больше.
Ну вот и проверяются у всех, кроме деления, явной командой типа jc или jo. А у деления — неявно и неустранимо. Неаккуратненько-с.
ЕМ>>>Потому, что перенос очень часто является следствием нормального выполнения, и как-то специально его обрабатывать не требуется, N>>Нет здесь такой несимметричности. ЕМ>Если сейчас навскидку скачать любой бинарник и дизассемблировать его — уверены, что действий со знаковыми величинами, при которых штатно возникает переполнение, найдем примерно столько же, сколько и для беззнаковых?
Да. С поправкой опять же на явные modulo типа счётчиков и номеров позиций. Или для беззнаковых даже больше таких ситуаций — см. вами же поднятую тему пару лет назад, где сравнивались итерирования по переменной в окрестностях нуля.
N>>где говорят про экономию ресурсов ЕМ>Экономия на флагах состояния на фоне сложности любого процессора даже 30-40-летней давности — это фикция, тех ресурсов там совершенно ничтожное количество, исчисляемое единицами логических элементов.
А теперь просто рассмотрите это как ещё 4 регистра (а в x86 даже 6, есть ещё PF и AF), которые надо отдельно учитывать во всём дизайне включая переименование регистров.
N>>где про резкое облегчение дизайна за счёт отсутствия единого регистра флагов и за счёт этого лучшую параллельность. ЕМ>Тоже непонятно, где здесь может быть "резкое облегчение". Параллельное выполнение даже простых арифметических операций требует наличия нескольких полноценных АЛУ, а флаги состояния из такого АЛУ выходят либо сами по себе, либо путем добавления единиц логических элементов. Некоторое упрощение получить можно, "резкое" — тупо неоткуда.
Ну здесь я могу сослаться только на авторитет тех товарищей, что на этом сильно больше собак съели — типа Ватермана.
N>>Заметьте, Intel в своём проекте APX намеревается сделать то же самое. ЕМ>В последнее время явно видна тенденция сращивания функций процессора и компилятора. Если существующие архитектуры еще предполагали написание программы человеком на ассемблере, то новые уже предполагают только машинную генерацию кода. В таких условиях разумно целиком оптимизировать связку "компилятор+процессор" — возможно, в ней флаги состояния действительно получаются избыточными.
О. Значит, таки это при каких-то условиях возможно?
ЕМ>Но и x86, и ARM проектировались во времена, когда написание кода человеком на ассемблере использовалось достаточно широко.
Верно. Вся линия RISC уже открыто декларировалась на то, что код будет в основном генерироваться компилятором и надо ему облегчать работу, а не человеку. "Под нож" в первую очередь попали в этом случае сложные методы адресации — как PDP-11 и вслед ей VAX и M68k любили всякие @(Rn)+ ... а x86 не успел их ввести и поэтому меньше пострадал в начале 90-х.
ЕМ>>>Это было бы следуюшим по разумности вариантом при отказе от исключения. N>>Как раз более разумно, чем исключение ЕМ>Если предполагается, что программа всегда будет генерироваться автоматически, и статистика показывает, что затраты на проверку после каждого деления потеряются на общем фоне, то да.
Достаточно не "всегда", а в подавляющем большинстве случаев. Что и имеем.
EM>>> Порождать исключения для арифметических переполнений нет смысла, поскольку они очень часто возникают в совершенно нормальных, запланированных ситуациях. N>>Кажется, единственный вариант, при котором это возможно, это арифметика "по модулю". Назвать такое "очень часто" — это слишком сильная натяжка. ЕМ>Например, там, где нуль/ненуль нужно преобразовать в 0/1 или 0/-1, компиляторы вовсю используют комбинации из neg, sbb, inc и and.
Я читал Hackerʼs Delight, да. Там таких примеров много. Но для x86 всё-таки test + setcc проще. Для ARM аналогично, с поправкой, что test == ands, и варианты csel позволяют сразу формировать значения типа -1 (csinv по условию). Для RISC-V, для сравнения, bool(rs==0) пишется как sltiu rd,rs,1, а bool(rs!=0) — sltu rd,x0,rs. Вообще одна команда. Ну если нужно -1, то да, ещё инвертировать знак (sub rd,x0,rd). То есть в таком режиме действие даже упрощается. И никакого таки скрытого переполнения
EM> А счетчики с переполнением часто используются для отслеживания небольших временнЫх интервалов в алгоритмах реального времени.
И от общего количества кода для процессора таких будет где-то 0.001%. Вряд ли больше. Ну ладно, в очень embedded — 0.1%.
N>>мы знаем, что "нормальных, запланированных" ситуаций с переполнениями почти нет ЕМ>Хорошо Вам, что "вы знаете". Я вот их использую регулярно, и столь же регулярно вижу в коде, который делает компилятор (те же преобразования int в bool).
И он регулярно использует эту извращённую последовательность из четырёх команд? Зачем?
EM> А вот операций с заведомо знаковыми величинами, при которых знаковое же переполнение было бы штатной ситуацией, и не требовало специальных действий, я с ходу даже не припомню, как и в случае деления на нуль.
Да, их мало. Я действительно не могу вспомнить характерные примеры.
Но вы сделали ошибку вот в чём: вы отождествляете беззнаковые и модульные типы. А это разные типы, в нормальных местах, а не извращенческих вроде C/C++.
В честных беззнаковых тоже переполнение как штатная ситуация как-то не присутствует.
ЕМ>>>чтобы в ситуации, когда что-то пошло не так, не было риска забыть проверить возвращаемое значение в ситуации, когда не существует заведомо безопасного значения для нештатной ситуации. N>>Ну и почему на это плюют во всяких x86 для трёх операций из четырёх (это ещё и если не считать сдвиги за арифметику со степенью двойки, тогда окажется, что в 7 из 8)? ЕМ>Где можно найти примеров, в которых это "наплевательство" требуется обставлять ловушками?
Вообще-то где угодно, где нет гарантии согласно проверенным локально данным, что переполнения нет.
ЕМ>>>Тогда и в плюсовых исключениях тоже нет смысла. Не в их неправильном использовании, а в механизме, как твковом. N>>Передёргиваете. Я ясно сказал, что возможность проверки есть и там, где её применяют, проблема детектируется. Может, чуть заморочно. ЕМ>Пытаюсь увидеть разницу, но не вижу. Если в процессоре не возбуждать исключения при делении на нуль, а возвращать специальное значение, необходимо добавлять проверку после каждого деления; случаев, когда программа может безопасно использовать специальное значение, найдется очень мало.
И в этом предложении можно заменить "деление" на "умножение", "сложение", "вычитание" с ровно таким же успехом. Только вместо деления на 0 будет какое-то из переполнений. Почему тогда не делать, что любая подобная операция вызывает исключение?
N>>случаи проблем из-за непойманного переполнения при остальных трёх арифметических операциях — уже десятки. ЕМ>Этих тоже хватало. Но, если б каждое такое переполнение порождало исключение, было бы еще хуже.
Чем хуже? Везде некорректное значение, которое ломает дальнейшую логику.
N>>Проверка каждого результата при укладке в целевую переменную, на её границы, плюс операций с базовым размером значения (как int и long в C) на переполнения. Не сильно большая цена за реальную безопасность. ЕМ>Это было бы полезно во всех без исключения языках, но не безусловно, а при возможности независимого управления каждым видом проверок.
Да, и я примерно в эту же сторону комментирую при каждой возможности последние надцать лет.
N>>Ну вот вы почему-то постановили, что константы разрядности в виде 32 и 64 они оправданны, а остальные — нет. ЕМ>Это не "мы постановили", это непосредственно вытекает из физических, железных характеристик архитектуры.
Нет. Тотальная двоичная иерархия размеров, сложившаяся в последние десятилетия, это чисто вопрос базового удобства на несколько процентов. Другие размеры тоже существуют и используются.
EM> А числа вроде 2 Гб для границы АП, или 480 Мб для бессбойной загрузки Win95, ниоткуда не вытекают, а возникают произвольно.
Половина всего адресного размаха — что тут произвольного?
N>>жалобы при переходе на S/360, что 32-битный float был заметно хуже 36-битного по свойствам. ЕМ>Вроде неудивительно. Чем не устраивал 64-битный?
Дороже в разы.
N>>Надо было таки оставить разрядности типа 36 и 72? ЕМ>Они и так оставались доступными через 64- и 128-разрядные. Или Вы о хранении чисел в памяти?
Нет, я о том, что был 36-битный формат float соответственно размеру слова машины, и у него были нормальные характеристики. А когда S/360 форсировала те же 32 бита слова, и пришлось влезать в 32 бита для float, пришлось делать диверсии в формате — начиная с base16 вместо base2, от чего резко ухудшилась точность.
64-битный float был сильно дороже, 128-битного не было.
N>>увеличение выше 2GB реально стоило — мороки программистам и производительности ядру. Сплошная перекачка данных между буферами. ЕМ>Почему при границе в 2 Гб "сплошной перекачки" нет, а при смещении на те же 3 Гб вдруг потребовалась?
Это зависело не от границы, а от объёма RAM. Чтобы не было перекачек, нужно, чтобы виртуальное адресное пространство полностью покрыло 2*RAM+MMIO, ещё и с потерями на фрагментацию каталогов. При переходе примерно к 1.5GB RAM это перестало выполняться. Хотеть деление виртуального пространства 3:1 или 3.5:0.5 начали уже при наличии 4-8GB RAM, до этого не было таких желающих.