Разработка аллокатора
This commit is contained in:
@@ -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`.
|
||||
* Все «заклинания» работают только в тестовом режиме веселья.
|
||||
|
||||
> **Вывод:** даже в мире строгих вычислений есть место магии, абсурду и улыбке. Пусть этот эксперимент напоминает нам, что программирование — это ещё и творчество!
|
||||
@@ -167,7 +167,7 @@ typedef struct FXGradedMemoryPool {
|
||||
**Таракан отвечавший за раздел свалил в неизвестном направлении...**
|
||||
|
||||
# 26.04.2026
|
||||
Что ж, примерное представление о работе сети и нагрузках на асинхронный ввод-вывод мы получили, но, мы брали в рассчёт Lineage2 где достаточно высокая вариативность пакетов, теперь вернёмся к нашему проекту прикинем примерную вариативность пакетов, учтём железо на котором будет работать сервер и посмотрим сколько он сможет выдержать клиентов в теории. На что в первую очередь стоит обратить внимание:
|
||||
Что ж, примерное представление о работе сети и нагрузках на асинхронный ввод-вывод мы получили, но, мы брали в расчёт Lineage2 где достаточно высокая вариативность пакетов, теперь вернёмся к нашему проекту прикинем примерную вариативность пакетов, учтём железо на котором будет работать сервер и посмотрим сколько он сможет выдержать клиентов в теории. На что в первую очередь стоит обратить внимание:
|
||||
* Железо
|
||||
* Ресурсы потребляемые ОС
|
||||
* Ресурсы потребляемые сторонними сервисами при их наличии(Web-сервер, почтовый сервер и т.д.)
|
||||
@@ -290,19 +290,17 @@ guiuser@felexdev:~$ cat /proc/sys/fs/file-max
|
||||
guiuser@felexdev:~$ ulimit -n
|
||||
open files (-n) 1024 < Максимальное количество файловых дескрипторов на процесс
|
||||
```
|
||||
Ничего, лично я,— "пингвин со стажем", можем поднять и до $65 535$ на процесс, однако на данном этапе нам нет такой необходимости.
|
||||
Ничего, лично я,— "пингвин со стажем", можем поднять и до $200 000$ на процесс, однако на данном этапе нам нет такой необходимости.
|
||||
|
||||
# 27.04.2026
|
||||
|
||||
На часах давно уже сегодня, пора пошугать тараканов, кофе налил, семья спит, продолжаем...
|
||||
|
||||
О сути расчётов по вафляю, что они нам дают 426к+ клиентов - весьма сомнительное число, но почему-бы на вложить его в основу, а вот почему: не учтены заголовки TCP/IP, а это не много ни мало - минимум 40 байт, соответственно - количество полезной нагрузки на сетевой трафик из наших расчётов будет 25:40, пересчитываем размер пакета: `$\frac{85,3×10^6}{65×8}≈163961$` guiuser-ов, вот, это уже ближе к теме.
|
||||
|
||||
**Предварительный итог профилирования сети:** расчётное время между аллокациями оценено ~2,5 мкс, что критически мало, это, конечно не самое худшее что может быть, но, и не так уж красиво, среднее время на выделение оптимизированными аллокаторами ~10-15 мкс, есть куда расти.
|
||||
О сути расчётов по вафляю, что они нам дают 426к+ клиентов - весьма сомнительное число, но почему-бы не вложить его в основу, а вот почему: не учтены заголовки TCP/IP, а это не много ни мало - минимум 40 байт, соответственно - количество полезной нагрузки на сетевой трафик из наших расчётов будет 25:40, пересчитываем размер пакета: $\frac{85,3×10^6}{65×8}≈163961$ guiuser, вот, это уже ближе к теме.
|
||||
|
||||
## RAM
|
||||
|
||||
Примерные цифры по сети мы получили, пора заняться RAM. Очередной раз обращаемся к нашему любимому критику-статисту Алисе(она "очень могёт" в статистике), идём препрофилировать память, на глаз прикиываем примерное минимальное потребление памяти на одного абьюзера:
|
||||
Примерные цифры по сети мы получили, пора заняться RAM. Очередной раз обращаемся к нашему любимому критику-статисту — Алисе(она "очень могёт" в статистике), идём препрофилировать память, на глаз прикиываем примерное минимальное потребление памяти на одного абьюзера:
|
||||
|
||||
**Таблица потребления памяти с выравниванием до 8 байт**
|
||||
| Компонент | Размер (байт) |Выравнивание|Итого с padding| Описание |
|
||||
@@ -311,7 +309,7 @@ open files (-n) 1024 < Максималь
|
||||
|epoll_event | 12 | 8 → 16 | 16 | Структура события epoll |
|
||||
|file descriptor | 8 | 8 → 8 | 8 | Указатель на файловый дескриптор |
|
||||
|socket struct | 200 | 8 → 200 | 200 | Базовая структура сокета |
|
||||
|**Метаданные соединения** | | | | |
|
||||
|**Метаданные соединения** | | | | |
|
||||
|Указатель на игру | 8 | 8 → 8 | 8 | Указатель на структуру игры |
|
||||
|XOR-ключи | 16 | 8 → 16 | 16 | 2 ключа шифрования |
|
||||
|Состояние игры | 64 | 8 → 64 | 64 | Данные состояния игры |
|
||||
@@ -321,7 +319,7 @@ open files (-n) 1024 < Максималь
|
||||
|**Дополнительные указатели**| | | | |
|
||||
|Указатель на клиента | 8 | 8 → 8 | 8 | Указатель на структуру клиента |
|
||||
|Резерв | 8 | 8 → 8 | 8 | Дополнительный резерв |
|
||||
|Указатель на пул | | | | |
|
||||
|**Указатель на пул** | | | | |
|
||||
|Указатель на клиента в пуле| 16 | 8 → 16 | 16 | Хранение клиента в пуле |
|
||||
**Итого с выравниванием** | | | **360** | **Суммарное потребление** |
|
||||
|
||||
@@ -329,38 +327,214 @@ open files (-n) 1024 < Максималь
|
||||
| Параметр | Значение | Описание
|
||||
|:----------------------|:-------------:|:--------------------------------------|
|
||||
| Доступная RAM 6.1 GB | | Свободная память для соединений |
|
||||
| Память на соединение | 360 байт | Потребление на одно соединение |
|
||||
| Теоретический максимум| ~16.9 млн | Максимальное количество соединений |
|
||||
| Реальный максимум | ~12.7 млн |С учетом системных накладных расходов |
|
||||
| Память на соединение | 360 байт | Потребление на одно соединение |
|
||||
| Теоретический максимум| ~16.9 млн | Максимальное количество соединений |
|
||||
| Реальный максимум | ~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