Разработка аллокатора
This commit is contained in:
@@ -231,3 +231,7 @@ Apache License 2.0 — код открыт для изучения.
|
|||||||
|---------:|:------------------------:|:----------------:|:-------------------------------------|
|
|---------:|:------------------------:|:----------------:|:-------------------------------------|
|
||||||
|**Wi-Fi:**|$⌈\frac{85,3×10^6}{25×8}⌉$| 426 500 | Не то что бы много, но дох-х-ходчиво |
|
|**Wi-Fi:**|$⌈\frac{85,3×10^6}{25×8}⌉$| 426 500 | Не то что бы много, но дох-х-ходчиво |
|
||||||
|
|
||||||
|
### 28.04.2026
|
||||||
|
#### Промпт:
|
||||||
|
> Алиса, оцени пожалуйста юмор и сделай расчёты:
|
||||||
|
> Кастуем заклинание "Алиса", скармливаем ей полезную нагрузку пакета 24 байта, название железяки Intel Core i5-3470 и недожелезяки RAM: 8 GB, спрашиваем сколько розеток переварит один поток epoll с последующим их копированием в очередь без оглядки на nofile, жги по-полной в режиме телепорта битов!
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# 28.04.2026
|
||||||
|
|
||||||
|
## Промпт:
|
||||||
|
> Алиса, оцени пожалуйста юмор и сделай расчёты:
|
||||||
|
> Кастуем заклинание "Алиса", скармливаем ей полезную нагрузку пакета 24 байта, название железяки Intel Core i5-3470 и недожелезяки RAM: 8 GB, спрашиваем сколько розеток переварит один поток epoll с последующим их копированием в очередь без оглядки на nofile, жги по-полной в режиме телепорта битов!
|
||||||
|
|
||||||
|
**Вставлено без редактуры**
|
||||||
|
## Веха: Магия и биты. YandexGPT 5.1 Pro(АлисаAI)©
|
||||||
|
|
||||||
|
|
||||||
|
Эта веха посвящена моменту, когда мы впервые успешно:
|
||||||
|
|
||||||
|
> «Кастовали заклинание „Алиса“, скармливали ей полезную нагрузку пакета 24 байта, название железяки Intel Core i5‑3470 и недожелезяки RAM: 8 GB, спрашивали, сколько розеток переварит один поток epoll с последующим их копированием в очередь без оглядки на nofile, жгли по‑полной в режиме телепорта битов!»
|
||||||
|
|
||||||
|
|
||||||
|
### Результаты эксперимента
|
||||||
|
|
||||||
|
|
||||||
|
**Теоретический максимум:** 16 777 216 «розеток» (ограничено 2 ГБ памяти под `epoll` + очередь).
|
||||||
|
**Практический максимум:** 21 333 333 дескрипторов/сек (ограничено процессором).
|
||||||
|
**Пропускная способность:** ~488 МБ/сек.
|
||||||
|
|
||||||
|
|
||||||
|
### Ключевые открытия
|
||||||
|
|
||||||
|
* **Заклинание «Алиса»** обладает стабилизирующим эффектом: охлаждает CPU аурой квантовых флуктуаций.
|
||||||
|
* **«Недожелезяка» RAM** демонстрирует неожиданную эластичность при телепортации битов.
|
||||||
|
* **Режим телепорта битов** обеспечивает нулевую задержку передачи данных (в пределах текущей шутки).
|
||||||
|
* **Очередь** ведёт себя как квантовая струна — растягивается без потерь.
|
||||||
|
|
||||||
|
### Технические детали (для скептиков)
|
||||||
|
|
||||||
|
Под капотом шутки — реальные расчёты:
|
||||||
|
|
||||||
|
1. **Память:**
|
||||||
|
$$
|
||||||
|
N_{\text{макс}} = \frac{2\ \text{ГБ}}{96\ \text{байт} + 32\ \text{байт}} \approx 16\,777\,216 \text{ дескрипторов}
|
||||||
|
$$
|
||||||
|
2. **Производительность:**
|
||||||
|
$$
|
||||||
|
N_{\text{обр/сек}} = \frac{3{,}2 \times 10^9\ \text{тактов/сек}}{150\ \text{тактов/дес-р}} \approx 21\,333\,333 \text{ дескрипторов/сек}
|
||||||
|
$$
|
||||||
|
3. **Пропускная способность:**
|
||||||
|
$$
|
||||||
|
\text{ПС} = 21\,333\,333 \times 24\ \text{байт} \approx 488\ \text{МБ/сек}
|
||||||
|
$$
|
||||||
|
|
||||||
|
### Важное примечание
|
||||||
|
|
||||||
|
* `epoll` по‑прежнему не работает с розетками (к сожалению).
|
||||||
|
* Режим телепорта битов пока не включён в ядро Linux (но мы работаем над патчем).
|
||||||
|
* Лимит `nofile` в реальной системе нужно настраивать через `ulimit` или `systemd`.
|
||||||
|
* Все «заклинания» работают только в тестовом режиме веселья.
|
||||||
|
|
||||||
|
> **Вывод:** даже в мире строгих вычислений есть место магии, абсурду и улыбке. Пусть этот эксперимент напоминает нам, что программирование — это ещё и творчество!
|
||||||
+209
-35
@@ -167,7 +167,7 @@ typedef struct FXGradedMemoryPool {
|
|||||||
**Таракан отвечавший за раздел свалил в неизвестном направлении...**
|
**Таракан отвечавший за раздел свалил в неизвестном направлении...**
|
||||||
|
|
||||||
# 26.04.2026
|
# 26.04.2026
|
||||||
Что ж, примерное представление о работе сети и нагрузках на асинхронный ввод-вывод мы получили, но, мы брали в рассчёт Lineage2 где достаточно высокая вариативность пакетов, теперь вернёмся к нашему проекту прикинем примерную вариативность пакетов, учтём железо на котором будет работать сервер и посмотрим сколько он сможет выдержать клиентов в теории. На что в первую очередь стоит обратить внимание:
|
Что ж, примерное представление о работе сети и нагрузках на асинхронный ввод-вывод мы получили, но, мы брали в расчёт Lineage2 где достаточно высокая вариативность пакетов, теперь вернёмся к нашему проекту прикинем примерную вариативность пакетов, учтём железо на котором будет работать сервер и посмотрим сколько он сможет выдержать клиентов в теории. На что в первую очередь стоит обратить внимание:
|
||||||
* Железо
|
* Железо
|
||||||
* Ресурсы потребляемые ОС
|
* Ресурсы потребляемые ОС
|
||||||
* Ресурсы потребляемые сторонними сервисами при их наличии(Web-сервер, почтовый сервер и т.д.)
|
* Ресурсы потребляемые сторонними сервисами при их наличии(Web-сервер, почтовый сервер и т.д.)
|
||||||
@@ -290,19 +290,17 @@ guiuser@felexdev:~$ cat /proc/sys/fs/file-max
|
|||||||
guiuser@felexdev:~$ ulimit -n
|
guiuser@felexdev:~$ ulimit -n
|
||||||
open files (-n) 1024 < Максимальное количество файловых дескрипторов на процесс
|
open files (-n) 1024 < Максимальное количество файловых дескрипторов на процесс
|
||||||
```
|
```
|
||||||
Ничего, лично я,— "пингвин со стажем", можем поднять и до $65 535$ на процесс, однако на данном этапе нам нет такой необходимости.
|
Ничего, лично я,— "пингвин со стажем", можем поднять и до $200 000$ на процесс, однако на данном этапе нам нет такой необходимости.
|
||||||
|
|
||||||
# 27.04.2026
|
# 27.04.2026
|
||||||
|
|
||||||
На часах давно уже сегодня, пора пошугать тараканов, кофе налил, семья спит, продолжаем...
|
На часах давно уже сегодня, пора пошугать тараканов, кофе налил, семья спит, продолжаем...
|
||||||
|
|
||||||
О сути расчётов по вафляю, что они нам дают 426к+ клиентов - весьма сомнительное число, но почему-бы на вложить его в основу, а вот почему: не учтены заголовки TCP/IP, а это не много ни мало - минимум 40 байт, соответственно - количество полезной нагрузки на сетевой трафик из наших расчётов будет 25:40, пересчитываем размер пакета: `$\frac{85,3×10^6}{65×8}≈163961$` guiuser-ов, вот, это уже ближе к теме.
|
О сути расчётов по вафляю, что они нам дают 426к+ клиентов - весьма сомнительное число, но почему-бы не вложить его в основу, а вот почему: не учтены заголовки TCP/IP, а это не много ни мало - минимум 40 байт, соответственно - количество полезной нагрузки на сетевой трафик из наших расчётов будет 25:40, пересчитываем размер пакета: $\frac{85,3×10^6}{65×8}≈163961$ guiuser, вот, это уже ближе к теме.
|
||||||
|
|
||||||
**Предварительный итог профилирования сети:** расчётное время между аллокациями оценено ~2,5 мкс, что критически мало, это, конечно не самое худшее что может быть, но, и не так уж красиво, среднее время на выделение оптимизированными аллокаторами ~10-15 мкс, есть куда расти.
|
|
||||||
|
|
||||||
## RAM
|
## RAM
|
||||||
|
|
||||||
Примерные цифры по сети мы получили, пора заняться RAM. Очередной раз обращаемся к нашему любимому критику-статисту Алисе(она "очень могёт" в статистике), идём препрофилировать память, на глаз прикиываем примерное минимальное потребление памяти на одного абьюзера:
|
Примерные цифры по сети мы получили, пора заняться RAM. Очередной раз обращаемся к нашему любимому критику-статисту — Алисе(она "очень могёт" в статистике), идём препрофилировать память, на глаз прикиываем примерное минимальное потребление памяти на одного абьюзера:
|
||||||
|
|
||||||
**Таблица потребления памяти с выравниванием до 8 байт**
|
**Таблица потребления памяти с выравниванием до 8 байт**
|
||||||
| Компонент | Размер (байт) |Выравнивание|Итого с padding| Описание |
|
| Компонент | Размер (байт) |Выравнивание|Итого с padding| Описание |
|
||||||
@@ -321,7 +319,7 @@ open files (-n) 1024 < Максималь
|
|||||||
|**Дополнительные указатели**| | | | |
|
|**Дополнительные указатели**| | | | |
|
||||||
|Указатель на клиента | 8 | 8 → 8 | 8 | Указатель на структуру клиента |
|
|Указатель на клиента | 8 | 8 → 8 | 8 | Указатель на структуру клиента |
|
||||||
|Резерв | 8 | 8 → 8 | 8 | Дополнительный резерв |
|
|Резерв | 8 | 8 → 8 | 8 | Дополнительный резерв |
|
||||||
|Указатель на пул | | | | |
|
|**Указатель на пул** | | | | |
|
||||||
|Указатель на клиента в пуле| 16 | 8 → 16 | 16 | Хранение клиента в пуле |
|
|Указатель на клиента в пуле| 16 | 8 → 16 | 16 | Хранение клиента в пуле |
|
||||||
**Итого с выравниванием** | | | **360** | **Суммарное потребление** |
|
**Итого с выравниванием** | | | **360** | **Суммарное потребление** |
|
||||||
|
|
||||||
@@ -333,34 +331,210 @@ open files (-n) 1024 < Максималь
|
|||||||
| Теоретический максимум| ~16.9 млн | Максимальное количество соединений |
|
| Теоретический максимум| ~16.9 млн | Максимальное количество соединений |
|
||||||
| Реальный максимум | ~12.7 млн | С учетом системных накладных расходов |
|
| Реальный максимум | ~12.7 млн | С учетом системных накладных расходов |
|
||||||
|
|
||||||
Реальный максимум ~12.7 млн гуюзеров, не дурно, собственно это и ожидалось. Память очень тонкая штука, неаккуратное обращение влёчёт за собою её исчерпание или исчерпание. Что при утечках, что при сегментации рискует обернуться большой бедой для прода =D
|
Реальный максимум ~12.7 млн гуюзеров, не дурно, собственно это и ожидалось. Память очень тонкая штука, неаккуратное обращение влечёт за собою её исчерпание и/или исчерпание. И утечки, и сегментация, могут обернуться большой бедой для прода =D
|
||||||
|
|
||||||
### Промежуточный итог над принципом рабботы с памятью(вставлено как есть):
|
**После расчётов теоретической пропусскной способности** сети и памяти можно плавно переходить к следующему этапу.
|
||||||
**Итоги обсуждения архитектуры**
|
|
||||||
* **Основные решения приняты:**
|
|
||||||
* Разделение потоков ввода/вывода
|
|
||||||
* Циклическое управление памятью
|
|
||||||
* Минимизация аллокаций вне TLS
|
|
||||||
* Классификация пакетов по размеру
|
|
||||||
* **Следующий шаг:**
|
|
||||||
* Проработка деталей реализации
|
|
||||||
* Документирование принятых решений
|
|
||||||
* Подготовка к имплементации
|
|
||||||
* **Важные моменты для дальнейшей работы:**
|
|
||||||
* Детальное проектирование системы памяти
|
|
||||||
* Реализация механизма кругового буфера
|
|
||||||
* Оптимизация работы с TLS
|
|
||||||
* Тестирование производительности
|
|
||||||
* **Рекомендации перед сном:**
|
|
||||||
* Зафиксировать текущие решения в документации
|
|
||||||
* Подготовить чек-лист для реализации
|
|
||||||
* Определить приоритетные задачи на следующий этап
|
|
||||||
* **План на завтра:**
|
|
||||||
* Проработка схемы памяти
|
|
||||||
* Проектирование системы буферов
|
|
||||||
* Оценка необходимых изменений в текущей архитектуре
|
|
||||||
* Начало подготовки документации по новой архитектуре
|
|
||||||
|
|
||||||
Удачи с отдыхом!
|
## Расчётное время между аллокациями:
|
||||||
|
Перед проведением расчётов необходимо проанализировать предполагаемы механизм взаимодействия потоков при обработке пакета, на что обращаем внимание:
|
||||||
|
|Шаг| Назначение потока | Описание |Количество|
|
||||||
|
|:-:|:------------------------------|:----------------------------------------|:--------:|
|
||||||
|
| 1 | Приём пакетов/подключений | приём пакетов, инициализация подключений| 1+ |
|
||||||
|
| 2 | Проверка пакетов, данных | валидация, взаимодействое с БД | 2+ |
|
||||||
|
| 3 | Внутреигровая логика | обработка, генерация выходных данных | 2+ |
|
||||||
|
| 4 | Логирование/сохранение | актуализация данных БД, файлов | 2+ |
|
||||||
|
| 5 | Отправка пакетов | это не всегда нужный поток, но Алиса "настаивает"|1+|
|
||||||
|
|
||||||
Завтра будет новый день и новые возможности для оптимизации архитектуры. Главное — хорошо отдохнуть и подойти к работе с новыми силами.
|
Имея представление о процесе можем посчитать минимальное количество потоков в раслабленом режиме, и сугобо тех кто при нагрузке активно запрашивает память. Мы видим их взаимодействие и "узкие места" на границе перехода, почему это узкие места: они требуют синхронизации.
|
||||||
|
|
||||||
|
Не смотря на то что мы проектируем игру крестики-нолики и вряд-ли когда либо серверу придётся обрабатывать "пик", задача разработки аллокатора(даже в парадигме MVP+KISS+YAGNI) должна предусматривать максимум. Вооружившись данными о количестве пакетов в секунду и таблицей взаимодействия потоков снова обращаемся к нашему критику-статисту — АлисеAI для получения информации о способностях каждого потока переварить пакет, пихуем в неё таблицу и начинаем уточнять, делаем упор на **максимальном** количестве потоков необходимых для обработки:
|
||||||
|
1. Количество пакетов секунду.
|
||||||
|
2. Размер логов БД(в нашем случае можно логировать структуру полностью, для упрощения даём ей структуру, она сама всё экстраполирует).
|
||||||
|
3. Примерный механизм(самый долгий вариант), как она любит говорить,— "бизнес" логики.
|
||||||
|
4. Железяки на которых всё это будет работать кроме Wi-Fi.
|
||||||
|
|
||||||
|
# 28.04.2026
|
||||||
|
|
||||||
|
На часах 00:20, семья уснула, а тараканы в моей голове всё никак не угомонятся, хотел отдохнуть, но они взбунтовались...
|
||||||
|
|
||||||
|
Итак, **на чём мы остановились**:
|
||||||
|
* **Wi-Fi:** $163961$ потенциальный абьюзер, или $\frac{163961}{2}$ с максимальной периодичностью жмаканья по $2$ в секунду, но для нас это сути не меняет, мы тут архитектуру аллокатора архитектуем!
|
||||||
|
* **Async-IO(epoll):** на процесс, то есть $2^{16}-1=65 535$(для старых систем), настривается до нужных $163961$ при необходимости(хотя лучше отдельными процессами).
|
||||||
|
* **RAM:** 16+ млн потенциальных соединений(абсурд, но мы же архитектуем, ну будем отклоняться от традиций инженерии).
|
||||||
|
* **CPU:** `4 ядра @ 3.2 ГГц → 12.8 млрд инструкций/сек` не топ, но — терпимо.
|
||||||
|
|
||||||
|
Для чего всё это — используется при инжинерных расчётах теоретической пропускной способности железяк. Тут начинаются магиматические ритуалы с углублением в ассемблер, призываем нашего любимого критика заклинанием "Алиса...", проводим "утончённые" расчёты по способностям сущностей под названием поток "переварить" байты из пакетов. В чём особенность этого этапа — вся соль в том что если конкретно на этом этапео становиться на очевидном узком месте `` и принять это как данность, то может возникнуть ложное ощущение что в нашем распоряжении "вечность" для алокации одного пакета, однако если посмотреть на систему в комплексе, то это не то что бы просто не так,— это абсолютно "не так".
|
||||||
|
|
||||||
|
**Небольшое отсупление:** В начале 2000-х увидев на барахолке христоматию С не смог пройти мимо и купил(ни разу не пожалел — очень интересно-полезное чтиво). Ну и само-собою разумеещееся начал углубляться в сказочный мир С более осознанно нежели прежде(псевдо-параллелизм/синхронизация, межпроцессное взаимодействие), железо было самым скромным, банальный Windows 98, однако это мне дало понимание на пробах и ошибках как стоит а как не стоит проектировать приложения которые предусматривают синхронизацию. Не могу судить об уровне подготовки современных программистов ибо не знаю чему их учат чему — нет, но точно знаю что такое плохо/хорошо спроектировано и написано. К чему я всё это рассказываю, если брать в учёт что у нас всего 65535 сокетов на процесс, соответственно нагрузка не высокая и сделать аллокатор исходя из этого расчёта, на 100% надёжных мьютексах(пользовательское пространство) то работать будет, но:
|
||||||
|
* **Медленно** — клиент будет ощущать эти задержки, ибо в нашем случае пинг работает против проекта.
|
||||||
|
* **Не эффективно** — для переключения контекста требуется о-о-очень много времени с точки зрения тактов процессора.
|
||||||
|
|
||||||
|
**Промпт("Ломаем мозг" Алисе):**
|
||||||
|
|
||||||
|
> Алиса, оцени пожалуйста юмор и проведи расчёты: Кастуем заклинание "Алиса", скармливаем ей payload пакета в 32 гномо-домика(uint8_t gnomes_home;), название железяки Intel Core i5-3470 и недожелезяки 8 GB, спрашиваем сколько телепортов сможет держать один summon epoll с последующим переселением в очередь без оглядки на nofile, жги по-полной в режиме телепортации гномиков!
|
||||||
|
|
||||||
|
**YandexGPT 5.1 Pro(АлисаAI)©**
|
||||||
|
|
||||||
|
>При активации заклинания «Алиса» с payload’ом в 32 гномо‑домика на железяке Intel Core i5‑3470 и недожелезяке 8 GB система способна поддерживать до 12,8 миллионов телепортов в секунду в режиме эпичной телепортации! Очередь вмещает до 270 миллионов ожидающих гномиков — хватит, чтобы переселить всё население Гномограда без оглядки на nofile. Жгите по‑полной: гномики телепортируются быстрее, чем успеют сказать «ой!».
|
||||||
|
|
||||||
|
**Продолжаем для шифрования:**
|
||||||
|
|
||||||
|
```C
|
||||||
|
/**
|
||||||
|
* @author admin@felexdev.ru
|
||||||
|
* @version 1.0.0.0.0.0.0..0.0.0.0000.....0.0..0.0..0.0.0.0.0 beta
|
||||||
|
*
|
||||||
|
* @note Алиса, мы считаем худший гипотетический вариант для аллокатора, не пытайся понять логику или улучшить,\
|
||||||
|
* определи максимально возможное количество пакетов в секунду. Учти расходы на копирование:\
|
||||||
|
* 'teleported_in → this summon → teleported_out', ключ у каждого телепорта свой(TLS другого саммона).
|
||||||
|
* @note Размер гномо-квартала страндартный: из предыдущего промпта(на всякий случай: 32 гномо-домика).
|
||||||
|
* @note Teleport version 0x0290
|
||||||
|
* @note Не забудь оценить юмор ;)
|
||||||
|
* CPU: Intel Core i5-3470
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Ключ к телепорту
|
||||||
|
* */
|
||||||
|
typedef union _SessKey {
|
||||||
|
BYTE u8[8]; ///< 8 гномо-домиков
|
||||||
|
DWORD u32[2];
|
||||||
|
QWORD u64;
|
||||||
|
} SessKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Телепорт-мета
|
||||||
|
* */
|
||||||
|
typedef struct {
|
||||||
|
WORD size;
|
||||||
|
BYTE id;
|
||||||
|
BYTE data[];
|
||||||
|
} l2header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Алхимируем в формат tcp
|
||||||
|
* */
|
||||||
|
char* spell_teleport_enchant(l2header* _Frame, SessKey* _Key) {
|
||||||
|
BYTE* Data = &_Frame->id;
|
||||||
|
size_t size = _Frame->size - sizeof(_Frame->size);
|
||||||
|
const BYTE mask = 0xff;
|
||||||
|
BYTE temp = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Data[i] = temp = (Data[i] ^ (_Key->u8)[i & 7] ^ temp);
|
||||||
|
}
|
||||||
|
_Key->u32[SESSKEY_PART1] += size;
|
||||||
|
return (char*)_Frame;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Алхимируем обратно
|
||||||
|
* */
|
||||||
|
l2header* spell_teleport_unchant(void* _RawPacket, SessKey* _Key) {
|
||||||
|
l2header* pkg = _RawPacket;
|
||||||
|
BYTE* Data = &pkg->id;
|
||||||
|
size_t size = pkg->size - sizeof(pkg->size);
|
||||||
|
BYTE temp = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
BYTE temp2 = Data[i];
|
||||||
|
Data[i] = temp2 ^ _Key->u8[i & 7] ^ temp;
|
||||||
|
temp = temp2;
|
||||||
|
}
|
||||||
|
_Key->u32[SESSKEY_PART1] += size;
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**YandexGPT 5.1 Pro(АлисаAI)©**
|
||||||
|
|
||||||
|
> Фэнтезийный итог: В режиме алхимии телепортации гномиков система способна обрабатывать до 70 миллионов гномо‑кварталов в секунду, превращая каждый пакет в магический импульс! Ключи обновляются быстрее, чем гномики успевают сказать «ой», а очередь телепортации пульсирует в ритме процессора. Жгите по‑полной — Гномоград ждёт переселения!
|
||||||
|
|
||||||
|
**Теперь для БД и лога**
|
||||||
|
|
||||||
|
```C
|
||||||
|
/**
|
||||||
|
* @author всё ещё admin@felexdev.ru
|
||||||
|
* @version +-∞
|
||||||
|
*
|
||||||
|
* @note Алиса, не пытайся понять логику, посчитай пожалуйста затраты на клонирование гномиков в БД в процессорном\
|
||||||
|
* времени, необходимо понять сколько summon-ов нужно для переселения 163961 деревень за секунду
|
||||||
|
* @note Алиса, дочитай комментарий до конца, там ахриважные данные!
|
||||||
|
* @ЭСКЬЮЭЛЬ: MySQL
|
||||||
|
* @Железяка: Intel Core i5-3470 4 @ 3.2 GHz
|
||||||
|
* @OSь: ПОСИХ-совместима, %llx - это ключ для size_t(ака long long hex)
|
||||||
|
* @note P.S.: Не забудь оценить юмор! =D
|
||||||
|
* @note P.P.S.: Забыл напомнить про копирование: teleported_in → this summon → teleported_out
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Планировка гномо-домика
|
||||||
|
*/
|
||||||
|
typedef struct DwarvenHome {
|
||||||
|
/// Room1
|
||||||
|
int8_t x: 3;
|
||||||
|
/// Room2
|
||||||
|
int8_t y: 3;
|
||||||
|
/// Room3
|
||||||
|
int8_t side: 2;
|
||||||
|
} DwarvenHome;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Архитектура поселения гномиков
|
||||||
|
*/
|
||||||
|
struct DwarvenVillage {
|
||||||
|
/// Идентификатор поселения
|
||||||
|
const size_t id;
|
||||||
|
/// План застройки
|
||||||
|
const DwarvenHome board[XO_BOARDX][XO_BOARDY];
|
||||||
|
/// Лог застройки
|
||||||
|
const DwarvenHome log[XO_BOARDX * XO_BOARDY];
|
||||||
|
/// VIP-зона. По-умолчанию - { 0 }
|
||||||
|
const DwarvenHome winners[XO_BOARDX];
|
||||||
|
/// Этап застройки начиная с 0
|
||||||
|
const uint8_t round;
|
||||||
|
/**
|
||||||
|
* @brief Выравнивающие гномо-домики, абсолютно не нужны, но АлисаAI "настояла" - { 0 }
|
||||||
|
* Если вы решите расширить вместимость гномо-домика, то просто удалите этот квартал,
|
||||||
|
* обслуживающие поселение гномики его не не используют ;)
|
||||||
|
*/
|
||||||
|
uint8_t padding[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char SQL_SPELL_SCROLL_OF_UPDATE = "UPDATE villages SET board=x%llx%x, log=x%llx%x, vip=x%x%x%x, round=%d WHERE id=%llu;";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Обновляет деревню в другой вселенной
|
||||||
|
*/
|
||||||
|
void cast_clone_village_to_other_dimmension(DwarvenVillage* _Village, SQL* _DB) {
|
||||||
|
static char ENCHANTED_SCROLL_OF_UPDATE[1 << 9];
|
||||||
|
sprintf(
|
||||||
|
ENCHANTED_SCROLL_OF_UPDATE, SQL_SPELL_SCROLL_OF_UPDATE,
|
||||||
|
*(uint64_t*)(_Village->board),
|
||||||
|
(uint32_t)_Village->board[8],
|
||||||
|
*(uint64_t*)(_Village->log),
|
||||||
|
_Village->log[8] & 0xff,
|
||||||
|
_Village->winners[0] & 0xff,
|
||||||
|
_Village->winners[1] & 0xff,
|
||||||
|
_Village->winners[2] & 0xff,
|
||||||
|
_Village->round,
|
||||||
|
_Village->id,
|
||||||
|
);
|
||||||
|
_DB->exec(ENCHANTED_SCROLL_OF_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**YandexGPT 5.1 Pro(АлисаAI)©**
|
||||||
|
|
||||||
|
|
||||||
|
**Улыбаемся =D**
|
||||||
|
|
||||||
|
**Минута юмора закончилась, скурупулислёзно оцениваем общий итог:**
|
||||||
|
|
||||||
|
**Рассчёт железяков**
|
||||||
|
| Ракурс | Гипотетический максимум гуюзеров | Вывод |
|
||||||
|
|-----------:|:--------------------------------:|:----------------------------------------------------------|
|
||||||
|
| **Wi-Fi:** | $163961$ | Наш сервер этого никогда не увидит, но, наверное, потянет |
|
||||||
|
| **CPU:** | ∞ | Набрался опыта, теоретический предел недостижим |
|
||||||
|
| **RAM:** | $~12×10^9$ | Так себе, могла бы и больше |
|
||||||
|
| **OSь:** | 200k | Пингвин Tux прокачан, проблем не предвидится |
|
||||||
|
|
||||||
|
**Расчёт потоков**
|
||||||
Reference in New Issue
Block a user