" title="Написать письмо">Написать письмо
На выжить после операций проктологии
2200 4002 2461 6363

Статистика

Пользователи : 1
Статьи : 2540
Просмотры материалов : 10975340
 
Скорости: от стека до кучи (10.11.2026). Печать E-mail
2026 - Ноябрь
10.11.2026 17:42
Save & Share
В написанном ранее генераторе хаотичных данных 369ГБ/с содержится функция измерения времени выполнения исходного кода. Так как удельные задержки составляли пикосекунды/байт - этой функции было уделено пристальное внимание на предмет точности вычислений. Не использовать в других целях такой выстраданный функционал - было бы глупо. И он был использован: чтобы обосрать гугл.


Гугл начал говорить, что в Borland C++ Builder куча медленнее стека в сотни раз: из-за операций выделения и освобождения памяти - но при этом чтение из неё равно скорости стека. Но стоит переформулировать запрос - и он пишет, что чтение из кучи медленнее стека во много раз из-за хаотичных прыжков по памяти до нужного значения. Переформулировал в 3-й раз - куча медленнее в чтении на 10-30%. Стало опять понятно, что вера - слепа, и уж точно её к гуглу применять нельзя (особенно после последнего разговора).

Итак, char cTemp[1] в 10-кратном цикле 4млдр вызовов, с вычетом времени цикла вызова, - отрицательное время на потоке частотой 3.57ГГц в неидеальных условиях (виртуалка, дочерняя ОС мешает + даже такого алгоритма не хватит на такую мелочь). Выносим в родительскую ОС на отдельный поток - опять отрицательное время выполнения. Не гордый - использовал гугла как раба и сгенерировал 100к записей по 40 в строке (компилируется - моё почтение: минуты 2-3). Перенёс вызов из Form_Activate в Form_Create (чтобы всплывающее окно и значок в трее не ели ресурсы). 224066-231286ГБ/с - корректный результат, с учётом убирания всех тормозящих факторов.

Далее приходит осознание собственной ошибки. Для char *cTemp = new char[1] (1 4-байтный указатель) более подходит запись char *cTemp[1] (массив с 1 4-байтным указателем), чем char cTemp[1] (массив из 1 1-байтного символа). Ну и кто мне припишет звёздочки к ста тысячам cTemp? Правильно: не гугл, а автозамена. И [1] она же сотрёт, чтобы был 1 4-байтный указатель, - полный аналог new. 893400-897210ГБ/с - выделение указателя всегда быстрее (есть к чему стремиться, в контексте ускорения генератора выше).

Память в сегменте данных, между стеком и кучей, - выделяется при запуске программы - стек, даже при своей бешеной скорости, уже проиграл. Настал черёд кучи через new. Внутренний цикл понижается до 200млн и внешний цикл до 1 (2ГБ памяти - предел для 32-битного Borland C++ Builder v.6.0). Abnormal program termination. Потому что в 64-битной родительской ОС указатель 8Б - значит, указанные выше скорости надо умножить на 2 ещё: учитывалась 1 итерация как 4Б. Ну, чтобы не убивать результаты, new тоже учитывается как 4Б - "0.0733-0.0737ГБ/с".

Усредняя: инициализация в стеке - в 12.18млн раз быстрее, чем в куче. И это ещё без учёта, что после new не только delete надо делать, но ещё и NULL (о проблеме диких указателей - абзацем ниже).

Теперь нужно в циклах присвоить индекс цикла unsigned int (защита от кеширования) в заранее инициализированный указатель char*, считая его как 1Б с постоянным переполнением (может быть замедление за счёт runtime-проверок - поэтому добавляем unsigned). Программа падает из-за дикости указателя unsigned char *cTemp. Изменение конструкции: unsigned char cValue; unsigned char *cTemp = &cValue;. Лень мерить среднее - внешний цикл 100 при внутреннем 4млрд - 8.152ГБ/с. Теперь переменные делаются глобальными, чтобы их унесло в сегмент данных, - даже static не подписал, 26.596ГБ/с.

А сегмент данных-то побыстрее стека будет, раза в 3. И объём проверен 26МБ в своё время (при 64МБ - падает) - против 1МБ стека (увеличиваемый до 10МБ в настройках проекта). А в современных языках - он где 2ГБ, а где вообще не ограничен ничем. А теперь задайте вопрос ИИ гугла "какого х ты пздл всё это время?!" - и он найдёт аж 3 причины этого феномена: время на выделение памяти в стеке, кеширование ЦП, прямая индексация против относительной.

А что new? У кучи есть в этом тесте большое преимущество: не надо прыгать между адресами RAM, чтобы собрать нужные данные. И оказывается между стеком и сегментом данных - 12.736ГБ/с. Не, так дело не пойдёт: надо заставить программу метаться между адресами в RAM. Удалось выделить только 600МБ (External Exception EEFFACE) - 1.576ГБ/с. В почти 6 раз медленнее стека - при этом, хаос скорости при одной и той же операции (пляшет 1.1-1.99ГБ/с).

Теперь new надо сделать из сегмента данных, чтобы убедиться, что объект переместился в кучу. А вот ни хрена: new остался в сегменте данных - и шпарит 13ГБ/с. Какое-то недосегмент-недокуча получилось. Обратно перенёс в функцию, чтоб железно в кучу, - единицы ГБ/с. Это единственный непонятный эксперимент из прошедших.


(добавлено 11.11.2026) Протестировал граничный размер сегмента данных для Borland C++ Builder v.6.0. 52МБ (не МиБ). Между 52 и 53 мегабайтом - возникает неопределённость стабильности. Может заработать. Может ошибку линковки показать, убрать её и заработать. Может свалиться.

Таким образом, трата 16МиБ моим генератором - корректная величина, и у разработчика есть ещё 35.223МБ объёма для своих переменных.
Обновлено ( 11.11.2026 12:23 )
 
 

Последние новости


©2008-2026. All Rights Reserved. Разработчик - " title="Сергей Белов">Сергей Белов. Материалы сайта предоставляются по принципу "как есть". Автор не несет никакой ответственности и не гарантирует отсутствие неправильных сведений и ошибок. Вся ответственность за использование материалов лежит полностью на читателях. Размещение материалов данного сайта на иных сайтах запрещено без указания активной ссылки на данный сайт-первоисточник (ГК РФ: ст.1259 п.1 + ст.1274 п.1-3).

Много статей не имеет срока устаревания. Есть смысл смотреть и 2011, и даже 2008 год. Политика сайта: написать статью, а потом обновлять ее много лет.
Рекламодателям! Перестаньте спамить мне на почту с предложениями о размещении рекламы на этом сайте. Я никогда спамером/рекламщиком не был и не буду!
Top.Mail.Ru