Встречал немного софта, который генерировал 1900-й год. Встречал, который генерировал 19100-й - вот тут эффекты были поинтереснее. Например, в Usenet не ходили сообщения - сервер отказывался принимать правильные с 2000-м годом как слишком старые.
Через полтора года ещё взорвался переход через миллиард секунд Unixtime, тоже были последствия.
Вот тут - увы и ах. Прямо сейчас копаюсь в реально большом и важном проекте проекте, который написан на C начиная с 2018 (приблизительно), сетевая часть управления к транспортной железке (телеком, далее NDA). Проект действительно важный, счёт пользователей идёт на миллионы. Причём для связи с HAL там отдельная внутренняя сеть, так что тот C был не в тему, Go подошёл бы в разы лучше. Но - у кого-то там жуткая инерция мышления, что ли, или просто нанятые представители одной населённой страны иначе не умели. C, кстати, компилируется с -O0. Go точно был бы лучше:) До кучи надо сказать, что там ещё Yocto, и бутерброд из минимум трёх слоёв на некоторых пакетах вынуждает делать в патч-слоях патчи на патчи, иначе народ не справляется. Боюсь потерять последние волосы...
Это типовая ситуация при разработке - определяется один так называемый happy path, который соответствует поведению типичного клиента (а для диска клиент - драйвер) и всё пилится под него. Стандарт, конечно, где-то рядом присутствует, но ситуация типа "ой тут второй клиент ведёт себя иначе" вызывает взрыв мозга на всех уровнях, от топ-менеджеров и до последних тестеров, которые уже тест-планы заложили под строго определённую последовательность вызовов и дублировать тест-планы не хотят.
Уж поверьте тому, у кого пара последних проектов это embedded:) чтобы заставить команду отработать все комбинации, нужны недюжинные усилия, как правило, в стиле "не сделаете - пойду к конкуренту через дорогу, вы не одни тут".
Или вот уже историческое: http://agatcomp.ru/agat/Hardware/DZU/fl140k/fl140k_structure.shtml - почитайте про порядок инициализации сексенсора для конкретных операций. Не выполняешь запросы, в которых не видишь смысл - а оно не работает, потому что смысл был внутренний - какое-то состояние куда-то изменилось.
У некоторых устройств надо было, например, записывать новое состояние регистра управления два раза подряд. Почему так - ну вот чего-то недовернули. Причём баг был в ревизиях B1-B3 а потом снова D2, потому что кто-то что-то криво смержил. В продаже в основном D2, а тестовую плату тебе присылают для D3. А когда возмущаешься - присылают для C2. И потом двойную запись для регистра ты находишь дизассемблированием виндового драйвера. На вопрос "почему так"? получаешь тишину, потому что тикет до умных технарей не доходит, менеджер скрывает всё что может - ему так приказали - а простые технари сами нихрена не знают. В итоге оставляешь такое же дублирование на века.
Тут хоть каталог баек составляй, только надо чтобы NDA истёк:))
Пусть у вас пачка из нескольких команд — фиксированно и немного (Itanium — группами по 3 команды, количество групп прямо не ограничено), или нефиксированно и много (Эльбрус-4 — до 30). Какая-то часть из них кодирует операции только с регистрами — считаем, они доступны всегда, и на чтение и на запись. Какая-то обращается к памяти. Вот тут начинаются проблемы. Если у вас обыкновенная DRAM, у неё самая длительная операция это закрыть неактуальную строку (переписать из её кэша, который в самой микросхеме DRAM, в собственно DRAM-часть) и открыть заказанную (прочитать и переписать в тот кэш на борту DRAM). Эта операция в лучших представителях занимает около 25 нс, в "бюджетных" DDR4 до 40 нс. (Обозначается обычно tRAS или похоже.) В тактах процессора... ну умножьте на 4, если у него 4ГГц тактовая. А ещё надо добавить время на опознание, что данных нет ни в одном локальном кэше (обычно добавляется где-то до 30 тактов), нет ни у одного партнёра по SMP (может быть и ~50 тактов) и на чтение полной строки (64 байта на x86) из DRAM (ну, ещё десятка два тактов, там высокая параллельность) — спокойно можно добрать и до 300 тактов.
Это чрезвычайно высокая цифра, даже если сравнивать с супердорогими арифметическими операциями типа деления (128/64 на x86, считается, до 90 тактов).
Теперь представим себе поток команд. На x86 вполне может быть, что пока 30-я по счёту только-только прочиталась из памяти, 25-я раскодирована, 20-й назначили все внутренние регистры и она ждёт выполнения, 15-я выполняется, 10-я закончила и результаты готовы, но ждёт, пока предыдущие завершат операции, результат 7-й сидит во write queue на выходе в кэш, для 5-й заканчивают синхронизацию между кэшам и в SMP, 1-я наконец всё типа закончила (слила результат в кэш в строку, которая эксклюзивно принадлежит на запись текущему ядру). В это время 2-я задумчиво занимается делением, и её результаты будут ещё тактов через 40. Но она (2-я) пишет в регистр, поэтому не тормозит заметную остальных; её результаты будут применены только к 15-й команде, а результаты той — только к 24-й, поэтому с остальными можно работать. Я не преувеличиваю в цифрах — у Skylake, например, цепочка от "наконец заканчиваем, фиксируем результаты" до "выбрали, начинаем декодировать" может быть до 224 микроопераций.
Процессор сам вычисляет, какая команда от какой зависит. Есть очевидные зависимости по регистрам (типа, если 3-я записала в eax, а 5-я его читает, 5-я должна выполняться после 3-й). Есть зависимости по памяти (x86 настаивает на том, что все операции записи в память упорядочены по этим действиям записи — хотя вычисления в них не требуют такой зависимости). Получается такой себе DAG исполнений, внутри которого заметная свобода.
А теперь чем отличается EPIC? Само название: Explicitly parallel instruction computing. Параллельность рассчитана на этапе написания машинного кода (обычно — компилятором). Причём не в терминах "данная команда хочет результаты той, что на 1 5 раньше по цепочке" — такое бы требовало слишком много места для записи — а в виде группировок типа "данные команды друг на друга не влияют" (см. ниже), "можно параллелить сколько угодно по вкусу" и "а вот тут мы знаем явную зависимость, надо завершить все предыдущие до всех последующих". В доке по Itanium это выглядит так:
>> An instruction group is a sequence of instructions starting at a given bundle address and slot number and including all instructions at sequentially increasing slot numbers and bundle addresses up to the first stop, taken branch, Break Instruction fault due to a break.b, or Illegal Operation fault due to a Reserved or Reserved if PR[qp] is one encoding in the B-type opcode space. For the instructions in an instruction group to have well-defined behavior, they must meet the ordering and dependency requirements described below.
и вот главные слова — "must meet the ordering and dependency requirements". Автору машкода надо явно определить группы, в которых взаимовлияние минимизировано, и зафиксировать их. Дальше в доке много страшных слов, но вот одни из ключевых:
>> Between instruction groups, every instruction in a given instruction group will behave as though its read occurred after the update of all the instructions from the previous instruction group.
Процессор не имеет права посчитать, что какая-то команда из IG1 может быть выполнена одновременно с какой-то последующей IG2, если между ними стоит явный stop. Даже прочесть данные из памяти в регистр — потому что это называется update of architectural state. Память тормозит? Жди.
>> Within an instruction group, every instruction will behave as though its read of the register state occurred before the update of the register state by any instruction (prior or later) in that instruction group, except as noted in the Register dependencies and Memory dependencies described below.
[...]
>> Register dependencies: Within an instruction group, read-after-write (RAW) and write-after-write (WAW) register dependencies are not allowed (except пара незначительных исключений)
А это, наоборот, в одной группе не может быть зависимостей (как уже сказал — надо отбирать только независимые действия). Хотел исхитриться и применить результаты чтения сразу же? Обломись, бабка, мы на корабле.
Дальше в доке много чего — 100500 поправок, уточнений и исключений, словно специально, чтобы запутать всех и усложнить компилятор до предела. Но смысл основной тот же: пока на тех архитектурах, где процессор вычисляет зависимости на ходу (как x86), одна команда не тормозит соседних "товарок", пока её результаты не нужны, и может быть выделена из основного потока — на IA-64 такой свободы нет, учись предсказывать задержки по памяти — то, чего в принципе предсказать невозможно на обычном современном железе (если вы не занимаетесь Meltdownʼом).
Резонный вопрос — а почему вообще Intel решил, что возможно такую архитектуру сделать эффективной? А вот тут надо заглянуть в историю и заметить, что тогда же его топ-менеджмент попался на две удочки одновременно — первая под названием Rambus, а вторая — NetBurst (Pentium 4 должен был по тем планам стать последним x86). Супербыстрая DRAM плюс ориентация на потоковые SIMD действия (для "мультимедиа") и пренебрежение всеми остальными классами задач. Чем тут поможет SIMD? А именно тем, что для основных задач хорошо предсказывается необходимость подчитать память — можно заранее (на одну-две IG) сказать prefetch на нужный кусок, пока выполняются предыдущие, оно уже в L1. Но тут наступил облом — не стала мультимедия единственным использованием компьютера, а Rambus мало того, что выпустила память с бо́льшими задержками, так и оказалось, что все новомодные усовершенствования это фикция, а заодно патентный буллинг (Intel потеряла ок. 4e8$$, насколько помню).
Так что EPIC эффективен только там, где вы можете строго ограничить время одной даже самой длительной команды. Видимо, из подобных соображений Intel исключил из IA-64 простое целочисленное деление — он знал, что это долго, но "не знал" того же про чтение DRAM. Если у вас SRAM (умножьте цену памяти на 10-20) — ok, вперёд. Если у вас DSP (тоже, считаем, SRAM) — тоже пойдёт, туда подобные архитектуры внедрились и устоялись. Но для "обычного" современного компа, для толстого сервера — ой, зась.
И вслед этому очевидный вопрос про "импортозаместительный" Эльбрус-4. На синтетических тестах он много чего показывает, но про реальные задачи идёт много подпольных отзывов про жуткие тормоза...
Использовался французский дюйм, но с 1985 года значение изменено: 2,707005 см.
Это сейчас. Это не историческое значение, как когда-то, например, австро-венгерский. Разница от английского - 6.5% - вся метрология сломается, если не заметить разницы.
Там ещё пачка исторических, которые могут тоже как-то взорваться, но уже на старой технике. Но если вы не уточняете, что современныйанглийский дюйм, можно хорошо влететь.
(редактор комментария - ужас, не понимаю, как управлять ссылками)
Ну так это и есть направление к тому, что должно было быть с самого начала.
В юзерленде вообще для 95% кода оптимизации вредны. В ядре требования повыше, но всё равно максимум проверок должен быть по умолчанию, а где не подходят - отключаться контекстными опциями.
Другой вопрос, а что делать в ядре, если проверка показывает нарушение. Проверять каждый чих явно - можно, но тогда стоит вопрос вылавливания кода, который пропустил эту проверку. Неявно значит система исключений, тогда надо развешивать обработчики; а если где-то вылетело необработанное, что, сразу паника? В общем, есть над чем думать.
Как уже сказал, доверие к такому источнику, про который вы знаете только подпись одним и тем же ключом, остаётся на уровне "верю, что это один и тот же человек писал" (ну, если мы предполагаем, что не сидят несколько под одним акаунтом и что коты ещё не умеют писать в Интернет что-то длиннее "ЯКОТ"). Для любого более серьёзного доверия нужен внешний источник. Но если человек подписывается, условно, Вася Пупкин на хабре, на LOR и в email и пишет на одни и те же темы со схожим уровнем компетенции, я могу считать, что это он и что его так зовут.
Во времена ранних PGP в крупных городах производились "сессии взаимной подписи" - в определённом месте собирались люди, которые друг у друга верифицировали документы (паспорт, права - что там где применяется) и тогда принимали друг у друга ключи - и подписывали их на публичных PGP-серверах. Не знаю, насколько эта традиция сейчас жива, давно не слышал.
Поскольку прямая передача между контрагентами в интернете исключена,
Она производится внесетевыми средствами, и на этом всё стоит. Ключи CA roots Мозиллы или корневые DNSSEC держатся на том, что люди, которые за них отвечают, регулярно встречаются вживую.
то остаётся второй способ.
Нет, не обязательно, и он точно не единственный, потому что сам вопрос доверия источнику публикации окончательно может быть решён только средствами вне Интернета.
то многие даже в подпись всех своих сообщений вставляли pgp fingerprint, являющийся хешем публичного ключа.
Которая давала только возможность сверить разные сетевые источники на то, что источник подписи один и тот же, но не давала возможность убедиться, например, что тот, кто подписывается Linus Torvalds, зовётся в реале так же, а не является, например, Аллой Пугачёвой, или тысячей индусов в одной локалке с шареным ключом.
[ɕ] как в нашем "щ", конечно, не точное [ç] - палатализованное против палатального - но ближайшее из того, как мы можем отразить их звук, и понятное им.
Регионы где произношение ближе к нашим "хь" или даже "х" есть, но их мало.
Давно реализовано (например в Olson TZ base так называемые right-зоны).
Только никому за пределами условных АЭС нахрен не нужно.
Не все.
Встречал немного софта, который генерировал 1900-й год. Встречал, который генерировал 19100-й - вот тут эффекты были поинтереснее. Например, в Usenet не ходили сообщения - сервер отказывался принимать правильные с 2000-м годом как слишком старые.
Через полтора года ещё взорвался переход через миллиард секунд Unixtime, тоже были последствия.
Объясните?
Это от ISA точно не зависит. Конкретный процессор "малинки" мог быть просто взят потому что простой и в пределах нужной цены.
EPARSE.
Вот тут - увы и ах. Прямо сейчас копаюсь в реально большом и важном проекте проекте, который написан на C начиная с 2018 (приблизительно), сетевая часть управления к транспортной железке (телеком, далее NDA). Проект действительно важный, счёт пользователей идёт на миллионы. Причём для связи с HAL там отдельная внутренняя сеть, так что тот C был не в тему, Go подошёл бы в разы лучше. Но - у кого-то там жуткая инерция мышления, что ли, или просто нанятые представители одной населённой страны иначе не умели. C, кстати, компилируется с -O0. Go точно был бы лучше:) До кучи надо сказать, что там ещё Yocto, и бутерброд из минимум трёх слоёв на некоторых пакетах вынуждает делать в патч-слоях патчи на патчи, иначе народ не справляется. Боюсь потерять последние волосы...
Вы про последовательность команд точно прочли?
Это типовая ситуация при разработке - определяется один так называемый happy path, который соответствует поведению типичного клиента (а для диска клиент - драйвер) и всё пилится под него. Стандарт, конечно, где-то рядом присутствует, но ситуация типа "ой тут второй клиент ведёт себя иначе" вызывает взрыв мозга на всех уровнях, от топ-менеджеров и до последних тестеров, которые уже тест-планы заложили под строго определённую последовательность вызовов и дублировать тест-планы не хотят.
Уж поверьте тому, у кого пара последних проектов это embedded:) чтобы заставить команду отработать все комбинации, нужны недюжинные усилия, как правило, в стиле "не сделаете - пойду к конкуренту через дорогу, вы не одни тут".
Или вот уже историческое: http://agatcomp.ru/agat/Hardware/DZU/fl140k/fl140k_structure.shtml - почитайте про порядок инициализации сексенсора для конкретных операций. Не выполняешь запросы, в которых не видишь смысл - а оно не работает, потому что смысл был внутренний - какое-то состояние куда-то изменилось.
У некоторых устройств надо было, например, записывать новое состояние регистра управления два раза подряд. Почему так - ну вот чего-то недовернули. Причём баг был в ревизиях B1-B3 а потом снова D2, потому что кто-то что-то криво смержил. В продаже в основном D2, а тестовую плату тебе присылают для D3. А когда возмущаешься - присылают для C2. И потом двойную запись для регистра ты находишь дизассемблированием виндового драйвера. На вопрос "почему так"? получаешь тишину, потому что тикет до умных технарей не доходит, менеджер скрывает всё что может - ему так приказали - а простые технари сами нихрена не знают. В итоге оставляешь такое же дублирование на века.
Тут хоть каталог баек составляй, только надо чтобы NDA истёк:))
Цитирую свой старый комментарий:
=== cut here ===
Пусть у вас пачка из нескольких команд — фиксированно и немного (Itanium — группами по 3 команды, количество групп прямо не ограничено), или нефиксированно и много (Эльбрус-4 — до 30). Какая-то часть из них кодирует операции только с регистрами — считаем, они доступны всегда, и на чтение и на запись. Какая-то обращается к памяти. Вот тут начинаются проблемы. Если у вас обыкновенная DRAM, у неё самая длительная операция это закрыть неактуальную строку (переписать из её кэша, который в самой микросхеме DRAM, в собственно DRAM-часть) и открыть заказанную (прочитать и переписать в тот кэш на борту DRAM). Эта операция в лучших представителях занимает около 25 нс, в "бюджетных" DDR4 до 40 нс. (Обозначается обычно tRAS или похоже.) В тактах процессора... ну умножьте на 4, если у него 4ГГц тактовая. А ещё надо добавить время на опознание, что данных нет ни в одном локальном кэше (обычно добавляется где-то до 30 тактов), нет ни у одного партнёра по SMP (может быть и ~50 тактов) и на чтение полной строки (64 байта на x86) из DRAM (ну, ещё десятка два тактов, там высокая параллельность) — спокойно можно добрать и до 300 тактов.
Это чрезвычайно высокая цифра, даже если сравнивать с супердорогими арифметическими операциями типа деления (128/64 на x86, считается, до 90 тактов).
Теперь представим себе поток команд. На x86 вполне может быть, что пока 30-я по
счёту только-только прочиталась из памяти, 25-я раскодирована, 20-й назначили все внутренние регистры и она ждёт выполнения, 15-я выполняется, 10-я закончила и
результаты готовы, но ждёт, пока предыдущие завершат операции, результат 7-й сидит во write queue на выходе в кэш, для 5-й заканчивают синхронизацию между кэшам
и в SMP, 1-я наконец всё типа закончила (слила результат в кэш в строку, которая
эксклюзивно принадлежит на запись текущему ядру). В это время 2-я задумчиво занимается делением, и её результаты будут ещё тактов через 40. Но она (2-я) пишет
в регистр, поэтому не тормозит заметную остальных; её результаты будут применены только к 15-й команде, а результаты той — только к 24-й, поэтому с остальными можно работать. Я не преувеличиваю в цифрах — у Skylake, например, цепочка от "наконец заканчиваем, фиксируем результаты" до "выбрали, начинаем декодировать" может быть до 224 микроопераций.
Процессор сам вычисляет, какая команда от какой зависит. Есть очевидные зависимости по регистрам (типа, если 3-я записала в eax, а 5-я его читает, 5-я должна выполняться после 3-й). Есть зависимости по памяти (x86 настаивает на том, что все операции записи в память упорядочены по этим действиям записи — хотя вычисления в них не требуют такой зависимости). Получается такой себе DAG исполнений, внутри которого заметная свобода.
А теперь чем отличается EPIC? Само название: Explicitly parallel instruction computing. Параллельность рассчитана на этапе написания машинного кода (обычно — компилятором). Причём не в терминах "данная команда хочет результаты той, что на 1
5 раньше по цепочке" — такое бы требовало слишком много места для записи — а в виде группировок типа "данные команды друг на друга не влияют" (см. ниже), "можно параллелить сколько угодно по вкусу" и "а вот тут мы знаем явную зависимость, надо завершить все предыдущие до всех последующих". В доке по Itanium это выглядит так:
>> An instruction group is a sequence of instructions starting at a given bundle
address and slot number and including all instructions at sequentially increasing slot numbers and bundle addresses up to the first stop, taken branch, Break Instruction fault due to a break.b, or Illegal Operation fault due to a Reserved or Reserved if PR[qp] is one encoding in the B-type opcode space. For the instructions in an instruction group to have well-defined behavior, they must meet the ordering and dependency requirements described below.
и вот главные слова — "must meet the ordering and dependency requirements". Автору машкода надо явно определить группы, в которых взаимовлияние минимизировано,
и зафиксировать их. Дальше в доке много страшных слов, но вот одни из ключевых:
>> Between instruction groups, every instruction in a given instruction group will behave as though its read occurred after the update of all the instructions from the previous instruction group.
Процессор не имеет права посчитать, что какая-то команда из IG1 может быть выполнена одновременно с какой-то последующей IG2, если между ними стоит явный stop. Даже прочесть данные из памяти в регистр — потому что это называется update of architectural state. Память тормозит? Жди.
>> Within an instruction group, every instruction will behave as though its read of the register state occurred before the update of the register state by any instruction (prior or later) in that instruction group, except as noted in the Register dependencies and Memory dependencies described below.
[...]
>> Register dependencies: Within an instruction group, read-after-write (RAW) and write-after-write (WAW) register dependencies are not allowed (except пара незначительных исключений)
А это, наоборот, в одной группе не может быть зависимостей (как уже сказал — надо отбирать только независимые действия). Хотел исхитриться и применить результаты чтения сразу же? Обломись, бабка, мы на корабле.
Дальше в доке много чего — 100500 поправок, уточнений и исключений, словно специально, чтобы запутать всех и усложнить компилятор до предела. Но смысл основной тот же: пока на тех архитектурах, где процессор вычисляет зависимости на ходу (как x86), одна команда не тормозит соседних "товарок", пока её результаты не нужны, и может быть выделена из основного потока — на IA-64 такой свободы нет, учись предсказывать задержки по памяти — то, чего в принципе предсказать невозможно на обычном современном железе (если вы не занимаетесь Meltdownʼом).
Резонный вопрос — а почему вообще Intel решил, что возможно такую архитектуру сделать эффективной? А вот тут надо заглянуть в историю и заметить, что тогда же его топ-менеджмент попался на две удочки одновременно — первая под названием Rambus, а вторая — NetBurst (Pentium 4 должен был по тем планам стать последним x86). Супербыстрая DRAM плюс ориентация на потоковые SIMD действия (для "мультимедиа") и пренебрежение всеми остальными классами задач. Чем тут поможет SIMD? А именно тем, что для основных задач хорошо предсказывается необходимость подчитать память — можно заранее (на одну-две IG) сказать prefetch на нужный кусок, пока выполняются предыдущие, оно уже в L1. Но тут наступил облом — не стала мультимедия единственным использованием компьютера, а Rambus мало того, что выпустила память с бо́льшими задержками, так и оказалось, что все новомодные усовершенствования это фикция, а заодно патентный буллинг (Intel потеряла ок. 4e8$$, насколько помню).
Так что EPIC эффективен только там, где вы можете строго ограничить время одной даже самой длительной команды. Видимо, из подобных соображений Intel исключил из IA-64 простое целочисленное деление — он знал, что это долго, но "не знал" того же про чтение DRAM. Если у вас SRAM (умножьте цену памяти на 10-20) — ok, вперёд. Если у вас DSP (тоже, считаем, SRAM) — тоже пойдёт, туда подобные архитектуры внедрились и устоялись. Но для "обычного" современного компа, для толстого сервера — ой, зась.
И вслед этому очевидный вопрос про "импортозаместительный" Эльбрус-4. На синтетических тестах он много чего показывает, но про реальные задачи идёт много подпольных отзывов про жуткие тормоза...
=== end cut ===
В embedded продолжают производить m68k based SoC и кто-то поддерживает Linux на них. Это уже легаси, да - иначе бы взяли что-то стиля STM32. Но есть.
1) Лучше говорить EPIC. VLIW это более широкое понятие.
2) Профилировка не сильно поможет при непредсказуемых задержках DRAM в сотни тактов.
Вот из свежей дискуссии на RSDN:
>> Под нее давно и регулярно [url=https://www.xda-developers.com/windows-arm-apps/]выпускаются сборки популярного софта[/url] (Photoshop/Lightroom, MS Office, Firefox, GIMP, VLC, Spotify, Netflix, Zoom, FAR, 7-Zip, PassMark, Python, Go, Node.js, VS 2022, VS Code, CMake, OpenVPN, SysInternals Suite), много мелкого софта, [url=https://www.pcgamingwiki.com/wiki/List_of_Windows_ARM_games]больше сотни игрушек[/url].
Я бы не сказал, что это "нечего ловить". Жизнь простого юзера без особых бизнес-приложений уже обеспечена.
Смотрим в вики:
Ключевое слово "обычно". И далее:
Это сейчас. Это не историческое значение, как когда-то, например, австро-венгерский. Разница от английского - 6.5% - вся метрология сломается, если не заметить разницы.
Там ещё пачка исторических, которые могут тоже как-то взорваться, но уже на старой технике. Но если вы не уточняете, что современный английский дюйм, можно хорошо влететь.
(редактор комментария - ужас, не понимаю, как управлять ссылками)
Телефон без одноразового будильника - диверсия сам по себе, независимо от TZ.
Ну так это и есть направление к тому, что должно было быть с самого начала.
В юзерленде вообще для 95% кода оптимизации вредны. В ядре требования повыше, но всё равно максимум проверок должен быть по умолчанию, а где не подходят - отключаться контекстными опциями.
Другой вопрос, а что делать в ядре, если проверка показывает нарушение. Проверять каждый чих явно - можно, но тогда стоит вопрос вылавливания кода, который пропустил эту проверку. Неявно значит система исключений, тогда надо развешивать обработчики; а если где-то вылетело необработанное, что, сразу паника? В общем, есть над чем думать.
Как уже сказал, доверие к такому источнику, про который вы знаете только подпись одним и тем же ключом, остаётся на уровне "верю, что это один и тот же человек писал" (ну, если мы предполагаем, что не сидят несколько под одним акаунтом и что коты ещё не умеют писать в Интернет что-то длиннее "ЯКОТ"). Для любого более серьёзного доверия нужен внешний источник. Но если человек подписывается, условно, Вася Пупкин на хабре, на LOR и в email и пишет на одни и те же темы со схожим уровнем компетенции, я могу считать, что это он и что его так зовут.
Во времена ранних PGP в крупных городах производились "сессии взаимной подписи" - в определённом месте собирались люди, которые друг у друга верифицировали документы (паспорт, права - что там где применяется) и тогда принимали друг у друга ключи - и подписывали их на публичных PGP-серверах. Не знаю, насколько эта традиция сейчас жива, давно не слышал.
Она производится внесетевыми средствами, и на этом всё стоит. Ключи CA roots Мозиллы или корневые DNSSEC держатся на том, что люди, которые за них отвечают, регулярно встречаются вживую.
Нет, не обязательно, и он точно не единственный, потому что сам вопрос доверия источнику публикации окончательно может быть решён только средствами вне Интернета.
Которая давала только возможность сверить разные сетевые источники на то, что источник подписи один и тот же, но не давала возможность убедиться, например, что тот, кто подписывается Linus Torvalds, зовётся в реале так же, а не является, например, Аллой Пугачёвой, или тысячей индусов в одной локалке с шареным ключом.
Да, и это тоже. "Боевой", "в боевую"...
Хорошее у них качество было, значит.
https://en.wikipedia.org/wiki/Standard_German_phonology#Ich-Laut_and_ach-Laut
[ɕ] как в нашем "щ", конечно, не точное [ç] - палатализованное против палатального - но ближайшее из того, как мы можем отразить их звук, и понятное им.
Регионы где произношение ближе к нашим "хь" или даже "х" есть, но их мало.
АО МежДелМаш. (Из фольклора 90-х)
Фефекцы фикции таки разные бывают. Это у нас и у немцев тяготеет к "с". А у ирландцев или кокни-англичан - к "ф". А есть регионы, где норма "т".
Продуктин (слышал неоднократно и мне нравится больше всего), продукция. "В продукции" звучит слегка нелепо но только до того, как привыкнешь.