惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog RSS Feed
宝玉的分享
宝玉的分享
腾讯CDC
博客园_首页
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
美团技术团队
P
Privacy International News Feed
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
D
DataBreaches.Net
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
S
Schneier on Security
G
GRAHAM CLULEY
博客园 - 三生石上(FineUI控件)
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
Forbes - Security
Forbes - Security
D
Docker
T
Tenable Blog
S
Secure Thoughts
雷峰网
雷峰网
S
Security @ Cisco Blogs
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
阮一峰的网络日志
阮一峰的网络日志

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Деконструкция GO: CPU, RAM и что там происходит. Системные вызовы. Часть 1.5
glibus · 2026-04-26 · via Все публикации подряд на Хабре

Итак, финал части 1! По крайней мере основного разбора без дополнений. Собственно, сегодня мы разберем то, чем в основном с точки зрения ядра ОС и CPU являются все вот эти ваши бэкенды – системные вызовы и всё, что вокруг них.

На самом деле механизм немного замудренный и “в лоб” сразу все эти системные вызовы мы разбирать не будем, потому что вокруг них существует ещё несколько концепций.

Итак, начнем!

User mode, Kernel mode

Процессор исполняет код в разных уровнях привилегий.

Это механизм защиты, который не позволяет пользовательским программам напрямую управлять системой. Зачем? Для безопасности. Чтобы чей-нибудь опасный ассемблерный вайбкод случайно всё не поломал!

Да и вообще, если бы любая программа могла выполнять любые инструкции CPU, она могла бы:

• Читать память других процессов

• Управлять устройствами

• Изменять таблицы страниц

• Выключать систему

Чтобы этого не происходило, CPU разделяет код по уровням доступа.

Хотя в архитектуре x86 существует 4 уровня привилегий:

Ring 0 – kernel mode

Ring 1 – драйверы

Ring 2 – системные службы и файлы

Ring 3 – user mode

По факту, Ring 1 и Ring 2 – это легаси, которое Американские деды проектировали с научной красотой, но без реальной производственной необходимости. В реальной жизни используются только 2 уровня – Ring 0 и Ring 3 для бОльшей совместимости софта с другими ОС, упрощения поддержки, да и вообще переключение уровней доступа дорогое(100-150 тактов CPU), соответственно, чем больше колец, тем хуже производительность.

Получается, что

В user mode выполняется обычный код программ.

Например:

• Браузер

• База данных

• Go runtime

• CLI утилиты

• Ваш вайбкод

В этом режиме запрещены инструкции, которые могут повлиять на систему. 

Например:

• Управление устройствами

• Изменение page tables

• Управление прерываниями

• Прямой доступ к физической памяти

Если программа попытается выполнить такую инструкцию, CPU сгенерирует exception(если что, это аппаратное прерывание).

В свою очередь, в kernel mode выполняется код операционной системы.

Здесь доступны все инструкции процессора.

Ядро может:

• Управлять памятью

• Планировать потоки

• Работать с драйверами устройств

• Управлять файловой системой

• Обрабатывать сетевые пакеты

Kernel mode обладает полным контролем над системой.

А теперь внимание!!!

Переход из user mode в kernel mode выполняется через системный вызов.

На x86-64 используется инструкция:

syscall

Давайте зафиксируем:

Системный вызов (system call) – обращение прикладной программы к ядру операционной системы для выполнения какой-либо операции.

Системные вызовы

Теперь рассмотрим более детально, что вообще происходит в этот момент.

Инструкция означает для процессора (CPU core), следующую последовательность действий

1) Переключить CPU в kernel mode

2) Передать управление ядру

3) Выполнение операции

После завершения происходит возврат:

sysret

Но, я уже понимаю, что возникают 2 вопроса: “Что значит “Передать управление ядру”?” и “Что ядро вообще должно исполнять?”

Давайте по порядку. Передача управления ядру происходит следующим образом:

1) CPU переключается из Ring 3 в Ring 0

2) Переключается на kernel stack

3) Загружается точка входа в kernel 

4) Управление передается обработчику системного вызова

В Linux x86-64 используется соглашение:

RAX – номер syscall

RDI – arg1

RSI – arg2

RDX – arg3

R10 – arg4

R8  – arg5

R9  – arg6

Это по сути аргументы системного вызова, которые именно вы и передаете

Что происходит после перехода в kernel mode?

1) Сохранение контекста процесса

2) По номеру системного вызова из RAX ядро находит обработчик в таблице sys_call_table

3) Выполнение операции

Инструкция syscall сохраняет адрес возврата в специальный регистр RCX(То есть RIP → RCX) и RFLAGS в R11, когда ядро закончит работу, инструкция sysret возьмет этот адрес и вернет процессор обратно в Ring 3 к вашей следующей строчке кода!

А что вообще за обработчики?

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

Например, для x86:

IA32_LSTAR – точка входа для системного вызова

IA32_STAR – сегменты перехода

IA32_FMASK – маска флагов

А номера системных вызовов?

Это просто соответствия, которые также загружаются нашей ОС. Например для linux можете посмотреть тут. 100% большинство из них узнаете!

А теперь давайте посмотрим путь самурая(зачеркнуто) системного вызова

Есть код в Go:

package main

import (
	"syscall"
)

func main() {
	msg := []byte("Yo bro!!!!\n")

	syscall.SyscallN(
		1,
		uintptr(1),
		uintptr(unsafe.Pointer(&msg[0])),
		uintptr(len(msg)),
	)
}

// func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno)

/*
trap → номер системного вызова
args → аргументы, которые полетят в системный вызов
trap = 1 = write(linux)
args[0] = 1
args[1] = указатель на буфер
args[2] = длина
*/

Внутри Go runtime вызывается asm-функция.

Для Linux x86-64 она выглядит примерно так:

MOVQ trap+0(FP), AX
MOVQ args+8(FP), DI
MOVQ args+16(FP), SI
MOVQ args+24(FP), DX
SYSCALL

Перед syscall:

RAX = номер системного вызова

RDI = arg1

RSI = arg2

RDX = arg3

То есть в нашем случае

RAX = 1

RDI = 1

RSI = &msg[0]

RDX = 11

Теперь что делает CPU:

Когда выполняется SYSCALL

Процессор

1) Переключается из Ring 3 → Ring 0

2) Сохраняет RIP в RCX

3) Сохраняет RFLAGS в R11

4) Загружает точку входа в kernel

Эта точка входа хранится в MSR:

IA32_LSTAR

Linux получает управление в entry_SYSCALL_64

Файл:

arch/x86/entry/entry_64.S

Дальше вызывается do_syscall_64

А теперь само ядро:

Ядро читает:

RAX = номер системного вызова и находит точку входа в обработчик в таблице.Для write это sys_write.

После чего обращаясь к драйверу терминала(если stdout) или файловой системы производим запись и далее sysret!

Разобрали только для Linux. Для Mac или Windows делать мы этого не будем, потому что получится долго и по большей части бессмысленно из-за похожести механизма по своему принципу!

Дороговизна системных вызовов и удешевление

Краткий ответ – да и еще раз да.

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

Само по себе переключение режима тоже чего-то да стоит. 100-150 тактов, как я ранее указал. Но помимо этого происходит также следующее:

  • Системный вызов действует как полный барьер памяти

  • Сохранение контекста(уже в самом коде ядра)

  • RIP → RCX, RFLAGS → R11

  • Остановка и перестройка пайплайна обработки команд(для обработки уже системного вызова)

  • Cache miss для команд и памяти(как правило)

И это только на вызове!!!

А после sysret

  • Переключается уровень доступа

  • Опять переключается контекст

  • Опять перестраивается пайплайн

Соответственно, стоимость системного вызова БЕЗ взаимодействия с устройством(например, принтером) – это где-то 150-400 циклов, а если взаимодействовать и с ними, то это может обойтись в несколько тысяч!

Если часто использовать системные вызовы, то CPU будет очень грустно из-за огромных накладных расходов, поэтому придумали разного рода оптимизации. Давайте рассмотрим их:

Буферизация

В Go например это будет выглядеть так:

w := bufio.NewWriter(os.Stdout)

w.WriteString("hello")

w.WriteString("guys")

w.Flush()

То есть реальный системный вызов только при w.Flush() и вместо двух write операций, мы получили одну!

Batch-операции

Некоторые системные вызовы позволяют передать сразу несколько операций.

К примеру:

  • writev

  • readv

  • sendmsg

  • recvmmsg

Вместо:

write

write

write

можно сделать writev и передать сразу несколько буферов.

И уменьшить количество переходов user → kernel

epoll

Если сервер работает с тысячами соединений, naïve подход выглядел бы так:

read(socket1)

read(socket2)

read(socket3)

Но большинство сокетов в данный момент ничего не имеют для чтения.

Каждый read – системный вызов. Представили боль CPU?

epoll решает проблему:

  1. Программа регистрирует сокеты в ядре ОС в специальной структуре данных, которая является красно-черным деревом(для файловых дескрипторов) с помощью epoll_ctl. Дерево помогает быстро искать по файловым дескрипторам.

  2. Ядро отслеживает события. То есть когда на сетевую карту что-то приходит, она создает аппаратное прерывание, а после чего драйвер сетевой карты передает в буфер конкретного сокета данные, как только данные приходят, срабатывает обработчик, с помощью которого сокет помещается в двусвязный список готовых событий(ReadyList).

  3. Приложение спрашивает, у кого есть данные. С помощью системного вызова epoll_wait программа получает доступ к готовым нужным ей событиям из Ready List, то есть ядро ОС копирует информацию о готовых событиях из этого самого списка!

Да, к слову, наш любимый netpoller из Go Scheduler точно так же использует данный системный вызов!

mmap

Иногда повторные системные вызовы можно вообще убрать.

Например, обычное чтение файла:

read(fd, buffer)

Каждое чтение требует системного вызова.

А mmap делает иначе:

файл отображается в память процесса

После этого чтение файла выглядит как обычный доступ к памяти

Zero-copy

Некоторые системные вызовы позволяют не копировать данные между user space и kernel space.

Например:

sendfile

splice

Обычный путь:

диск → kernel → user → kernel → сокет

sendfile делает:

диск → kernel → сокет

Без копирования в user space.

Думаю, необходимые механизмы и нюансы работы CPU(и даже частично операционной системы) мы разобрали, теперь пойду выйду из подвала, прогуляюсь и начнем уже разбирать непосредственно Go! Настоятельно рекомендую пробежаться по всей части целиком. Вот ссыль на первую статью.

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

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

0%Очень хорошо0

0%Хорошо0

0%Нейтрально0

0%Плохо0

0%Ужасно0

Никто еще не голосовал. Воздержавшихся нет.