Вообще то ELF файлы в память отображаются именно mmap'ом ;)
иначе любое обновление используемых библиотек или запущенных демонов заканчивалось бы ошибкой
Если бы при обновлении пакетный менеджер пытался просто открывать и писать в файл с бинарником, так бы и происходило. Но он всё таки действует умнее и сначала удаляет существующий файл. Надеюсь, не надо объяснять, как в UNIX обрабатывается удаление открытого файла.
Скорее просто нюансы планирования - после прерываний система ставит поток туда, куда удобнее. От перегрева это не особо спасает - никто не мешает задать affinity, тогда поток будет всегда на одном ядре; ну и всё таки ожидается, что процессор нормально работает когда все ядра загружены вычислениями. Перегрев фиксится троттлингом частоты.
Так в том то и дело, что полиморфизм нужен уже для того, чтобы работать через один и тот же API с файлами на разных FS. Сокеты и т.п. оверхеда не добавляют - они просто не реализуют часть методов.
Я же предлагаю вынести абстракции в код прикладных программ, и то, реализовывать их только там, где это необходимо.
Может ещё и явно в пользовательском коде вызывать разные read/write для разных файловых систем? Для них же разные реализации в ядре, приходится косвенный вызов делать...
Тут как и с счётным кодом важно, является ли код latency bound (скажем, проход по связному списку, случайно разбросанному по адресам) или throughput bound (когда предсказуемо читаем память подряд, как в примере в статье). В первом случае ускорение будет.
Просто некий unsigned long, который в разных устройствах может означать разные вещи. Параметры операции - так и вовсе список из переменного числа произвольных аргументов.
Во первых, свои модели - скажем, БК 0010 или Микроша - были разработаны и производились в классических советских учреждениях, кооперативы эти не занимались. Во вторых, к производству элементной базы кооперативы никакого отношения не имели - соотвественно, полноценной рыночной цепочки, когда спрос на компьютеры формирует спрос на производство и развитие микропроцессоров, не было. Рынка компьютерных игр и вообще софта для домашних компьютеров тоже не было - всё просто копировали друг у друга - отсюда и явное превосходство Спектрума в плане софтварной экосистемы.
А нужен ли вообще C сферическому новичку в вакууме? Всё таки это в первую очередь язык для тех, кому интересно, как реально код бежит на процессоре, и кто может конвертировать этот интерес в разработку софта (embedded, OS, компиляторы, прочие инструменты) - и обычно у таких людей какой то бэкграунд в программировании накапливается в школьные годы до знакомства с C.
вряд ли инлайн-асм в C/C++-коде обрабатывается компилятором так
Инлайн асм в 64битном cl.exe вообще вырубили, как раз из за невозможности нормально генерировать SEH правила.
Ради того, чтобы сэкономить восемь шестнадцать байт на стеке?
Скорее ради нескольких тактов процессора при каждом заходе в try блок, в каких то ситуациях может быть критично. Идея в том, что при отсутствии исключений try должен быть вообще бесплатным - то есть использовать его можно сколько угодно, лишь бы сами исключения не падали. Генерация правил в компиляторе дело наживное (в Юниксах .eh_frame секция давно использовалась), об усложнениях пишущих на ассемблере, видимо, не особо думали - директивы дали и ладно.
И SEH тоже испортили, убрав цепочку фреймов с стека. Чем руководствовались — загадка.
Тут то всё понятно - убрали дополнительный оверхед в прологе/эпилоге на работу с этой цепочкой. Раскрутка стека при исключениях стала заметно дороже - но предполагается, что исключения - это действительно исключения и случаются крайне редко.
PS Исследования на эту тему были, но не видел, чтобы заливалось в основной бранч.
Можете показать реализацию этой логики в исходном коде ядра?
Вообще то ELF файлы в память отображаются именно mmap'ом ;)
Если бы при обновлении пакетный менеджер пытался просто открывать и писать в файл с бинарником, так бы и происходило. Но он всё таки действует умнее и сначала удаляет существующий файл. Надеюсь, не надо объяснять, как в UNIX обрабатывается удаление открытого файла.
Скорее просто нюансы планирования - после прерываний система ставит поток туда, куда удобнее. От перегрева это не особо спасает - никто не мешает задать affinity, тогда поток будет всегда на одном ядре; ну и всё таки ожидается, что процессор нормально работает когда все ядра загружены вычислениями. Перегрев фиксится троттлингом частоты.
Так в том то и дело, что полиморфизм нужен уже для того, чтобы работать через один и тот же API с файлами на разных FS. Сокеты и т.п. оверхеда не добавляют - они просто не реализуют часть методов.
Ну да, те же read/write верхнего уровня, одинаковые для файла на диске, сокета или /dev/random
Дело скорее не в нюансах, а в том что только FS знает, куда конкретно на диске записать очередную порцию данных в файле.
Может ещё и явно в пользовательском коде вызывать разные read/write для разных файловых систем? Для них же разные реализации в ядре, приходится косвенный вызов делать...
Ну и кстати MCA на этих примерчиках корректно отрабатывает (но моделировать HT не умеет).
Я на подручном Haswell вижу полтора (и это логично, когда независимые операции раскладываются на два порта).
Тут как и с счётным кодом важно, является ли код latency bound (скажем, проход по связному списку, случайно разбросанному по адресам) или throughput bound (когда предсказуемо читаем память подряд, как в примере в статье). В первом случае ускорение будет.
Просто некий unsigned long, который в разных устройствах может означать разные вещи. Параметры операции - так и вовсе список из переменного числа произвольных аргументов.
Включая авторов Unix, выкинувших его в Plan 9.
Не упомянули ioctl(), с которым юниксовый файл является по сути объектом с произвольным интерфейсом.
Во первых, свои модели - скажем, БК 0010 или Микроша - были разработаны и производились в классических советских учреждениях, кооперативы эти не занимались. Во вторых, к производству элементной базы кооперативы никакого отношения не имели - соотвественно, полноценной рыночной цепочки, когда спрос на компьютеры формирует спрос на производство и развитие микропроцессоров, не было. Рынка компьютерных игр и вообще софта для домашних компьютеров тоже не было - всё просто копировали друг у друга - отсюда и явное превосходство Спектрума в плане софтварной экосистемы.
Навскидку (x ^ (x >> (sizeof(x)*8-1))) - (x >> (sizeof(x)*8-1))
А нужен ли вообще C сферическому новичку в вакууме? Всё таки это в первую очередь язык для тех, кому интересно, как реально код бежит на процессоре, и кто может конвертировать этот интерес в разработку софта (embedded, OS, компиляторы, прочие инструменты) - и обычно у таких людей какой то бэкграунд в программировании накапливается в школьные годы до знакомства с C.
Я это и имел в виду, неточно выразился.
Инлайн асм в 64битном cl.exe вообще вырубили, как раз из за невозможности нормально генерировать SEH правила.
Скорее ради нескольких тактов процессора при каждом заходе в try блок, в каких то ситуациях может быть критично. Идея в том, что при отсутствии исключений try должен быть вообще бесплатным - то есть использовать его можно сколько угодно, лишь бы сами исключения не падали. Генерация правил в компиляторе дело наживное (в Юниксах .eh_frame секция давно использовалась), об усложнениях пишущих на ассемблере, видимо, не особо думали - директивы дали и ладно.
Не раскрыта тема проверки корректности адресов возврата/перехода в железе (Intel CET, ARM PAC/BTI).
Практика программирования (Керниган/Пайк) - не только про C, но большая часть кода на нём.
Тут то всё понятно - убрали дополнительный оверхед в прологе/эпилоге на работу с этой цепочкой. Раскрутка стека при исключениях стала заметно дороже - но предполагается, что исключения - это действительно исключения и случаются крайне редко.