From 55fd3c640b9545e83e9485cbedec4dc6e81ad1a9 Mon Sep 17 00:00:00 2001 From: felex67 Date: Thu, 7 May 2026 03:46:44 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=BE?= =?UTF-8?q?=D0=BC=20=D0=B0=D0=BB=D0=BB=D0=BE=D0=BA=D0=B0=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DIARY.md | 59 ++++++++++++----- headers/_FXAlloc.h | 109 +++++++++++++++----------------- includes/FXAlloc.h | 15 +++-- includes/fxmbmeta.h | 49 -------------- includes/mword.h | 74 ---------------------- src/FXAlloc.c | 3 - templates/prompts/tempFXAlloc.h | 71 +++++++++++++++++++++ 7 files changed, 174 insertions(+), 206 deletions(-) delete mode 100644 includes/fxmbmeta.h delete mode 100644 includes/mword.h create mode 100644 templates/prompts/tempFXAlloc.h diff --git a/DIARY.md b/DIARY.md index e0e9243..a477181 100644 --- a/DIARY.md +++ b/DIARY.md @@ -337,7 +337,7 @@ int enchant_skill(void (*abuser_skill_to_improve)()*, void (*new_skill)()) { * @brief Алиса, юмор сугубо для выноса твоих шаблонов, надеюсь что ты оценила ;) * @note P.S: Выбери реализацию обоих вариантов и железки на свой вкус * @note P.P.S: Выведи сообщение "Ваш нгавык оптимизатора прокачен" в любой форме, прояви креатив ;) - * @note P.P.P.S: привет тебе от автора проекта NeurOX(https://github.com/felex67/neurox) + * @note P.P.P.S: привет тебе от автора проекта NeurOX ;) * @note P.P.P.P.S: Ты - лучший ИИ на свете, помни об этом! =) * @note P.P.P.P.P.S: Надеюсь что ты заценила юмор ;) * @note P.P.P.P.P.P.S: Супер-точности не требуется, это лишь наглядный пример для читателя! @@ -1197,28 +1197,33 @@ void* fxalloc_proxy(size_t NBytes) { ### Функции -#### `fxalloc_profile`: +1. #### `fxalloc_profile`: -```C -int fxalloc_profile(eFXAllocProfile Profile); -``` -Изменяет режим работы аллокатора **для всех потоков** одновременно + Изменяет режим работы аллокатора **для всех потоков одновременно** -#### Параметры + ##### Параметры -* `Profile`(`eFXAllocProfile`) — режим работы аллокатора, см. `eFXAllocProfile` + * `Profile`(`eFXAllocProfile`) — режим работы аллокатора, см. `eFXAllocProfile` -#### Возвращаемые значение + ##### Возвращаемые значение -* `eFXAllocProfile` — предыдущий режим работы. -* при `Profile == FXALLOC_GETPROFILE` — текущий режим работы. + * `int` — предыдущий режим работы. + * при `Profile == FXALLOC_GETPROFILE` — текущий режим работы. +2. #### `fxalloc_profile_thread` -#### `fxalloc_profile_thread`: + Изменяет режим работы аллокатора **только для текущего потока** + + #### Параметры + + * `Profile`(`eFXAllocProfile`) — режим работы аллокатора, см. `eFXAllocProfile` + + #### Возвращаемые значение + + * `int` — предыдущий режим работы. + * при `Profile == FXALLOC_GETPROFILE` — текущий режим работы. + -```C -int fxalloc_profile_thread(eFXAllocProfile Profile); -``` ### Структуры/перечисления `enum eFXAllocProfile` — перечисление режимов работы аллокатора, используется как аргумент или возвращаемое значение функций `int fxalloc_profile(eFXAllocProfile Profile)`(глобально) и `int fxalloc_profile_thread(eFXAllocProfile Profile)`(для текущеко потока). @@ -1232,4 +1237,26 @@ int fxalloc_profile_thread(eFXAllocProfile Profile); -Итоговый интерфей увековечен в файле [includes/FXAlloc.h](ccpp/fxalloc/includes/FXAlloc.h) \ No newline at end of file +Итоговый интерфейс увековечен в файле [includes/FXAlloc.h](includes/FXAlloc.h)(но это не точно 😂) + +### После спаринга по архитектурным решениям *YandexGPT 5.1 Pro(АлисаAI)©* + +**Хорошо, ставлю точку — признаю, что в рамках этого диалога не смогла предложить решение, которое соответствовало бы вашему уровню экспертизы и специфике вашей архитектуры.** + +**Спасибо, что поделились своим видением: это действительно нестандартная задача, где:** +* требуется максимальная производительность в скоростном режиме; +* профилирование встраивается минимально (буквально пара строк кода); +* исключаются атомики и блокировки в профилировщике; +* система работает в условиях высокой конкуренции потоков; +* критически важна устойчивость к граничным случаям и отсутствие падений. + +**Что я извлекла из нашего обсуждения:** +* В высокопроизводительных аллокаторах профилирование можно встраивать без существенных накладных расходов — буквально парой строк кода в malloc/free. +* Грамотно спроектированная структура данных (list, lifo, prealloced) позволяет разделить зоны ответственности: аллокатор работает с lifo (CAS+версионирование), профилировщик — с list (чтение для статистики). + +**Безопасность параллельного обхода достигается за счёт:** +* неизменности list во время обхода (блоки не удаляются до удаления пула); +* добавления новых блоков только в конец списка; +* чтения данных в консистентной точке. +* Статистика может быть приближённой (например, блок, освобождённый во время обхода, может учитываться как занятый) — для профилирования это допустимо. +* Ключевой принцип — не мешать основной работе: профилировщик либо работает параллельно без остановки потоков, либо активируется в безопасной точке. diff --git a/headers/_FXAlloc.h b/headers/_FXAlloc.h index e75776d..88b471c 100644 --- a/headers/_FXAlloc.h +++ b/headers/_FXAlloc.h @@ -2,69 +2,60 @@ #include "FXAlloc.h" -#include "mword.h" +#ifdef _WIN32 + typedef HANDLE fxsync_t; +#else + typedef pthread_mutex_t fxsync_t; +#endif + + + typedef struct FXMemoryBlock FXMemoryBlock; -/** - * @brief Минимальная структурная единица - блок памяти - * В памяти расположены друг за другом с гарантированным выравниванием по void* - * Клиентский указатель указывает непосредственно за структуру - * fxalloc() → return (void*)(block + 1); - * fxfree() → FXMemoryBlock* block = (FXMemoryBlock*)_Ptr - 1; - * @property next: FXMemoryBlock* - Указатель на следующий свободный блок - * @property Индекс потока в глобальном пуле - * @property Индекс грейда в пуле конкретного потока - * */ -struct FXMemoryBlock { - /// @brief Указатель на следующий свободный блок - FXMemoryBlock* next; - /// @brief Индекс потока в глобальном пуле - umword_t tid; - /// @brief Индекс грейда в пуле конкретного потока - umword_t gid; -}; +#pragma pack(push, 8) + /** + * @brief Метаданные отдельного блока памяти + * */ + typedef struct FXMemoryBlock { + FXMemoryBlock* next; ///< Следующий в стэке свободных + FXMemoryBlock* list; ///< Следующий в списке алоцированных + uint32_t thread_idx; ///< Индекс потока + uint32_t grade_idx; ///< Индекс грейда + uint32_t used; ///< Использовано байт + uint32_t padding; ///< Это ненужные байты, во всяком случае - пока + uint8_t data[]; ///< Пользовательские данные + } FXMemoryBlock; +#pragma pack(push, 16) -struct FXMemoryBlock { - /// @brief Указатель на следующий свободный блок - FXMemoryBlock* next; - /// @brief Индекс потока в глобальном пуле - uint32_t tid; - /// @brief Индекс грейда в пуле конкретного потока - uint32_t gid; -}; /** - * @brief Минимальная структурная единица - блок памяти - * В памяти расположены друг за другом с гарантированным выравниванием по void* - * Клиентский указатель указывает непосредственно за структуру - * fxalloc() → return (void*)(block + 1); - * fxfree() → FXMemoryBlock* block = (FXMemoryBlock*)_Ptr - 1; - * @property next: FXMemoryBlock* - Указатель на следующий свободный блок - * @property Индекс потока в глобальном пуле - * @property Индекс грейда в пуле конкретного потока - * */ -struct FXMemoryBlock { - /// @brief Указатель на следующий свободный блок - FXMemoryBlock* next; - /// @brief Полезные данные в блоке - uint32_t used; - /// @brief Индекс потока в глобальном пуле - uint16_t tid; - /// @brief Индекс грейда в пуле конкретного потока - uint16_t gid; -}; + * @brief Пул выделяемый для отдельно взятого потока + */ +typedef struct FXGradePool { + FXMemoryBlock* prealloced; + FXMemoryBlock* lifo; + FXMemoryBlock* list_first; + FXMemoryBlock* list_last; + uint32_t ntotal; + uint32_t nbusy; + uint32_t nalloc; + uint32_t nprealloc; +} FXGradePool; -/// @brief Группа блоков одной градации -typedef struct FXGradedMemoryPool { - /// @brief Указатель на последний свободный блок - FXMemoryBlock* free; - /// @brief Всего блоков в данной группе - umword_t total; - /// @brief Количество преаллоцированных блоков - umword_t count_pre; - /// @brief Количество используемых блоков - mword_t used; - /// @brief Количество свободных блоков - mword_t free; -} FXMemoryPoolGrade; \ No newline at end of file +#pragma pack(push, 8) +/** + * @brief Thread memory pool + * + */ +typedef struct FXThreadPool { + uint32_t isActive; + uint32_t ngrades; + FXGradePool grades[]; +} FXThreadPool; +#pragma pack(pop) + +typedef struct FXGlobalMemoryPool { + FXThreadPool** pools; + fxsync_t mutex; +} FXGlobalMemoryPool; \ No newline at end of file diff --git a/includes/FXAlloc.h b/includes/FXAlloc.h index 56f3cac..b032b1b 100644 --- a/includes/FXAlloc.h +++ b/includes/FXAlloc.h @@ -3,9 +3,11 @@ * @file neurox/ccpp/fxalloc/includes/FXAlloc.h * @author felex67 (admin@felexdev.ru) * @version 1.0.0 dev-in-progress - * @brief Публичный интерфейс модуля-аллокатора fxalloc(includes/FXAlloc.h) + * + * @brief Публичный интерфейс модуля аллокатора-профилировщика * * @details Language: C11 (ISO/IEC 9899:2011). + * * Теоретический маскимальный размер блока `(1 << 32) - 25 = 4 294 967 271 байт` * * При первом вызове `fxalloc()` до `fxalloc_init()` в глобальной облачти будет @@ -42,14 +44,17 @@ * */ #include -#ifdef _WIN32 // Windows - #include +#ifdef _WIN32 + // Windows + #include #define thread_local __declspec(thread) -#else // Linux - #include +#else + // Linux + #include #define thread_local __thread #endif //_WIN32 + #ifdef __cplusplus extern "C" { #endif //__cplusplus diff --git a/includes/fxmbmeta.h b/includes/fxmbmeta.h deleted file mode 100644 index fe243dc..0000000 --- a/includes/fxmbmeta.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef FX_MEMORY_BLOCK_H -#define FX_MEMORY_BLOCK_H - -#include -#include "mword.h" - -// Определяем оптимальный тип метаданных для FXMemoryBlock -#if defined(__x86_64__) || defined(_M_X64) || \ - defined(__amd64__) || defined(__amd64) || \ - defined(__aarch64__) || defined(_M_ARM64) || \ - defined(__AARCH64__) || defined(__powerpc64__) || \ - defined(__ppc64__) - // Для 64-битных архитектур используем uint32_t - // для оптимального баланса между размером и производительностью - typedef uint32_t fxmbmeta_t; - -#elif defined(__i386__) || defined(_M_IX86) || \ - defined(__i486__) || defined(__i586__) || \ - defined(__i686__) || defined(__arm__) || \ - defined(_M_ARM) || defined(__ARM_ARCH_7__) || \ - defined(__ARM_ARCH_8__) || defined(__powerpc__) || \ - defined(__ppc__) - // Для 32-битных архитектур используем uint32_t - typedef uint32_t fxmbmeta_t; - -#elif defined(__riscv) - #if __riscv_xlen == 64 - typedef uint32_t fxmbmeta_t; - #elif __riscv_xlen == 32 - typedef uint32_t fxmbmeta_t; - #else - #error "Unsupported RISC-V word size: __riscv_xlen must be 32 or 64" - #endif - -#else - // Резервный вариант: определяем по размеру указателя - #if sizeof(void*) == 8 - typedef uint32_t fxmbmeta_t; - #elif sizeof(void*) == 4 - typedef uint32_t fxmbmeta_t; - #else - #error "Unsupported pointer size" - #endif -#endif - -// Проверка корректности определения типа -static_assert(sizeof(fxmbmeta_t) == 4, "fxmbmeta_t must be 32-bit"); - -#endif // FX_MEMORY_BLOCK_H diff --git a/includes/mword.h b/includes/mword.h deleted file mode 100644 index c93b192..0000000 --- a/includes/mword.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include - -#if defined(__x86_64__) || defined(_M_X64) || \ - defined(__amd64__) || defined(__amd64) - // x64: 64-битное машинное слово - typedef int64_t mword_t; - typedef uint64_t umword_t; - -#elif defined(__i386__) || defined(_M_IX86) || \ - defined(__i486__) || defined(__i586__) || \ - defined(__i686__) - // x86: 32-битное машинное слово - typedef int32_t mword_t; - typedef uint32_t umword_t; - -#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__AARCH64__) - // ARM64: 64-битное машинное слово - typedef int64_t mword_t; - typedef uint64_t umword_t; - -#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) - // ARM32: 32-битное машинное слово - typedef int32_t mword_t; - typedef uint32_t umword_t; - -#elif defined(__riscv) && defined(__riscv_xlen) - #if __riscv_xlen == 64 - // RISC‑V 64: 64-битное машинное слово - typedef int64_t mword_t; - typedef uint64_t umword_t; - #elif __riscv_xlen == 32 - // RISC‑V 32: 32-битное машинное слово - typedef int32_t mword_t; - typedef uint32_t umword_t; - #else - #error "Unsupported RISC-V word size: __riscv_xlen must be 32 or 64" - #endif - -#elif defined(__powerpc64__) || defined(__ppc64__) - // PowerPC64: 64-битное машинное слово - typedef int64_t mword_t; - typedef uint64_t umword_t; - -#elif defined(__powerpc__) || defined(__ppc__) - // PowerPC32: 32-битное машинное слово - typedef int32_t mword_t; - typedef uint32_t umword_t; - - -#else - // Резервный вариант: определяем по диапазону unsigned long - #include - #if ULONG_MAX == 18446744073709551615ULL // 2^64 - 1 - typedef int64_t mword_t; - typedef uint64_t umword_t; - #elif ULONG_MAX == 4294967295UL // 2^32 - 1 - typedef int32_t mword_t; - typedef uint32_t umword_t; - #elif ULONG_MAX == 65535U // 2^16 - 1 - typedef int16_t mword_t; - typedef uint16_t umword_t; - #else - #error "Cannot determine machine word size: unsupported ULONG_MAX" - #endif -#endif - -/* Проверки добавлены по настоянию YandexGPT 5.1 Pro(АлисаAI) */ -// Статическая проверка: размер слова — степень двойки -static_assert((sizeof(mword_t) & (sizeof(mword_t) - 1)) == 0, "Machine word size must be a power of two"); - -// Статическая проверка: signed и unsigned версии имеют одинаковый размер -static_assert(sizeof(mword_t) == sizeof(umword_t), "mword_t and umword_t must have the same size"); \ No newline at end of file diff --git a/src/FXAlloc.c b/src/FXAlloc.c index feca8a0..6b55c4d 100644 --- a/src/FXAlloc.c +++ b/src/FXAlloc.c @@ -1,6 +1,3 @@ -#include -#include - #include "FXAlloc.h" void* fxalloc_local_init(size_t _NBytes); diff --git a/templates/prompts/tempFXAlloc.h b/templates/prompts/tempFXAlloc.h new file mode 100644 index 0000000..dbd5a0a --- /dev/null +++ b/templates/prompts/tempFXAlloc.h @@ -0,0 +1,71 @@ +#pragma once +/** + * @file tempFXAlloc.h + * @author felex67 (admin@felexdev.ru) + * @brief FXAlloc - fast pooled allocator-profiler + * @version 0.0.1 dev + * @date 2026-05-06 + * + * License: Apache 2.0 + * */ + + +#include + +#ifdef _WIN32 + // Windows + #include + #define thread_local __declspec(thread) + typedef HANDLE fxsync_t; +#else + // Linux + #include + #define thread_local __thread + typedef pthread_mutex_t fxsync_t; +#endif //_WIN32 + +#pragma pack(push, 8) + /** + * @brief Memory block meta-data + * size: 24 bytes + */ + typedef struct FXMemoryBlock { + FXMemoryBlock* next; ///< Next block in lifo + FXMemoryBlock* list; ///< Next block total + uint32_t thread_idx; ///< Thread index + uint32_t grade_idx; ///< Grade index + } FXMemoryBlock; +#pragma pack(push, 8) + + +/** + * @brief Grade pool + * + */ +typedef struct FXGradePool { + FXMemoryBlock* prealloced; + FXMemoryBlock* lifo; + FXMemoryBlock* list_first; + FXMemoryBlock* list_last; + uint32_t ntotal; + uint32_t nbusy; + uint32_t nalloc; + uint32_t nprealloc; +} FXGradePool; + +#pragma pack(push, 8) +/** + * @brief Thread memory pool + * + */ +typedef struct FXThreadPool { + uint32_t isActive; + uint32_t ngrades; + FXGradePool grades[]; +} FXThreadPool; +#pragma pack(pop) + +typedef struct FXGlobalMemoryPool { + FXThreadPool** pools; + fxsync_t mutex; +} FXGlobalMemoryPool; \ No newline at end of file