Загадки мозга

Тема в разделе "WASM.HEAP", создана пользователем Blackbeam, 19 июн 2011.

  1. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    667
    schuler,

    А должна быть разница в профайле, про шедулер слыхал что такое поточное квантование ?

    Что за школосходка!?
     
  2. schuler

    schuler New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2021
    Сообщения:
    17
    Ahimov, В Delphi 7 нет встроенного профайлера, замерял через GetTickCount, а надо было через QueryPerformanceCounter ? Какое поточное квантование? с школьным уровнем 9го класса, конечно не слышал. Просто ковырялся в старье начала 2000х годов и нарвался на этот код
     
  3. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    667
    schuler,

    Понятно, сразу бы сказал.

    Замер профайла бывает двух видов. Первый реализован архитектурно - взводится высокопр. таймер, он вызывает прерывания. Процедура обработки берет адрес останова потока и матем. индексирует счетчик в адресном массиве. Так мы видим где задача, тоесть поток провел больше времени. Мы это называем - обеспечить покрытие кода(cover).
    Второй тип - замер в цикле. Но тут нужно понимать что есть задача, поток и это дискретно. Система дает квант времени, затем забирает примерно 20ms задача исполняется, затем уходит в сон.
    Замер в цикле ты увидешь поточное квантование и и расчет производительности будет неверен, матем ошибка без учета планирования.

    Простой пример - есть решения, это конструкторы, с виксов. Ты на вход даешь код, он формирует граф и пересобирает код назад, обычно мутация еще, но не суть.
    Так для оптимизации сборки необходим механизм BDO, тут есть моя тема и я нашел решение. Но не суть - использовался примитивный механизм, уменьшаем ветвление и ребилдим весь граф. Был использован профайлер, который показал этот косяк.

    Наверно много написал, сорян за опечатки я с сенсора :)
     
    schuler нравится это.
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.395
    Ты сделал мой день. У индия к сожалению перья не держатся, приходится постоянно втыкать по делу и без.
     
  5. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    360
    Если хотите измерить время выполнения блока кода, просто создайте для этого благоприятную среду. Тогда и планировщик может не отобрать 30 мл/сек квант вашего потока. Шедулер передаёт управление только активным потокам в очереди, которые реально исполняются на данный момент. Если у вас открыто хоть 100 окон с разными приложениями, но все они находятся в фоне, планировщик не переключится ни на один из них, а будет постоянно отдавать квант только вашему профайлеру, окно которого висит на переднем плане.

    Но если в момент тестов у вас параллельно идёт, например, длительное копирование данных, тогда система отберёт ваш квант, и на такое-же время передаст его потоку копирования, после чего опять вернёт его вам. В общем случае нужно:

    1. Включить в биосе таймер HPET, чтобы получить от QueryPerfFreq() макс частоту 14 МГц.
    2. Закрыть все остальные приложения
    3. При помощи SetProcessAffinityMask(-1,1) оставить только 1 ядро ЦП
    4. Установить высокий приоритет своему потоку через SetPriorityClass(-1,HIGH_PRIORITY_CLASS), тогда у вас точно не отберут квант.
    5. Перед каждым замером очищать конвейер ЦП, например инструкцией lfence или cpuid.
    6. Иметь ввиду, что профилирование кода любыми методами не даёт 100% результата - всегда имеется погрешность.

    Вот небольшое приложение на fasm'e, которое измеряет длительность инструкций rdtsc, lfence, и api Sleep(500). Каждый тест производится не 1, а 5 раз подряд, после чего нужно выбрать наибольшее значение. Код показывает и частоту счётчика QPC - если она меньше 10 Мгц, значит HPET в системе не работает, и нужно включить его через bcd.

    profiler.png
     

    Вложения:

    • Profiler.zip
      Размер файла:
      5,5 КБ
      Просмотров:
      20
    Mikl___, Ahimov и schuler нравится это.
  6. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    34
    Первый адоб фотошоп был написан на паскале.

    Код (Pascal):
    1. {Photoshop version 1.0.1, file: Huffman.pas
    2.   Computer History Museum, www.computerhistory.org
    3.   This material is (C)Copyright 1990 Adobe Systems Inc.
    4.   It may not be distributed to third parties.
    5.   It is licensed for non-commercial use according to
    6.   www.computerhistory.org/softwarelicense/photoshop/ }
    7.  
    8. PROGRAM Huffman;
    9.  
    10. TYPE
    11.     PNode = ^TNode;
    12.     TNode = RECORD
    13.         leaf: BOOLEAN;
    14.         code: INTEGER;
    15.         entry: INTEGER;
    16.         branch: ARRAY [0..1] OF PNode
    17.         END;
    18.  
    19.     Str255 = STRING [255];
    20.  
    21. VAR
    22.     id: INTEGER;
    23.     root: PNode;
    24.     word: Str255;
    25.     code: INTEGER;
    26.     entry: INTEGER;
    27.  
    28. PROCEDURE AddCode (node: PNode; code: INTEGER; VAR word: Str255);
    29.  
    30.     VAR
    31.         branch: INTEGER;
    32.  
    33.     BEGIN
    34.  
    35.     IF LENGTH (word) = 0 THEN
    36.         BEGIN
    37.  
    38.         IF node^.leaf OR (node^.branch [0] <> NIL) OR
    39.                          (node^.branch [1] <> NIL) THEN
    40.             BEGIN
    41.             WRITELN ('? Conflict for code ', code:1);
    42.             EXIT (PROGRAM)
    43.             END;
    44.  
    45.         node^.leaf := TRUE;
    46.         node^.code := code
    47.  
    48.         END
    49.  
    50.     ELSE
    51.         BEGIN
    52.  
    53.         IF word [1] = '0' THEN
    54.             branch := 0
    55.         ELSE IF word [1] = '1' THEN
    56.             branch := 1
    57.         ELSE
    58.             BEGIN
    59.             WRITELN ('? Invalid word for code ', code:1);
    60.             EXIT (PROGRAM)
    61.             END;
    62.  
    63.         DELETE (word, 1, 1);
    64.  
    65.         IF node^.branch [branch] = NIL THEN
    66.             BEGIN
    67.  
    68.             NEW (node^.branch [branch]);
    69.  
    70.             node^.branch [branch]^.leaf := FALSE;
    71.             node^.branch [branch]^.branch [0] := NIL;
    72.             node^.branch [branch]^.branch [1] := NIL
    73.  
    74.             END;
    75.  
    76.         AddCode (node^.branch [branch], code, word)
    77.  
    78.         END
    79.  
    80.     END;
    81.  
    82. PROCEDURE NumberNode (node: PNode);
    83.     BEGIN
    84.  
    85.     node^.entry := entry;
    86.  
    87.     entry := entry + 1;
    88.  
    89.     IF node^.branch [0] <> NIL THEN NumberNode (node^.branch [0]);
    90.     IF node^.branch [1] <> NIL THEN NumberNode (node^.branch [1])
    91.  
    92.     END;
    93.  
    94. PROCEDURE WriteHexDigit (x: INTEGER);
    95.     BEGIN
    96.     IF x <= 9 THEN
    97.         WRITE (x:1)
    98.     ELSE
    99.         WRITE (CHR (ORD ('A') + x - 10))
    100.     END;
    101.  
    102. PROCEDURE WriteHex (x: INTEGER);
    103.     BEGIN
    104.     WriteHexDigit (BAND (BSR (x, 12), $F));
    105.     WriteHexDigit (BAND (BSR (x, 8), $F));
    106.     WriteHexDigit (BAND (BSR (x, 4), $F));
    107.     WriteHexDigit (BAND (x, $F))
    108.     END;
    109.  
    110. PROCEDURE WriteNode (node: PNode);
    111.     BEGIN
    112.  
    113.     WRITE ('    $"');
    114.  
    115.     IF node^.leaf THEN
    116.         WriteHex (node^.code)
    117.     ELSE
    118.         WriteHex (-1);
    119.  
    120.     WRITE (' ');
    121.  
    122.     IF node^.branch [0] <> NIL THEN
    123.         WriteHex (node^.branch [0]^.entry)
    124.     ELSE
    125.         WriteHex (-1);
    126.  
    127.     WRITE (' ');
    128.  
    129.     IF node^.branch [1] <> NIL THEN
    130.         WriteHex (node^.branch [1]^.entry)
    131.     ELSE
    132.         WriteHex (-1);
    133.  
    134.     WRITELN ('"');
    135.  
    136.     IF node^.branch [0] <> NIL THEN WriteNode (node^.branch [0]);
    137.     IF node^.branch [1] <> NIL THEN WriteNode (node^.branch [1])
    138.  
    139.     END;
    140.  
    141. BEGIN
    142.  
    143. NEW (root);
    144.  
    145. root^.leaf := FALSE;
    146. root^.branch [0] := NIL;
    147. root^.branch [1] := NIL;
    148.  
    149. READLN (id);
    150.  
    151. WHILE NOT EOF DO
    152.     BEGIN
    153.  
    154.     READ (code);
    155.     READLN (word);
    156.  
    157.     WHILE (word [1] = ' ') OR
    158.           (word [1] = CHR (9)) DO
    159.         DELETE (word, 1, 1);
    160.  
    161.     WHILE (word [LENGTH (word)] = ' ') OR
    162.           (word [LENGTH (word)] = CHR (9)) DO
    163.         DELETE (word, LENGTH (word), 1);
    164.  
    165.     AddCode (root, code, word)
    166.  
    167.     END;
    168.  
    169. entry := 0;
    170.  
    171. NumberNode (root);
    172.  
    173. WRITELN ('data ''HUFF'' (', id:1, ', purgeable)');
    174. WRITELN ('    {');
    175.  
    176. WriteNode (root);
    177.  
    178. WRITELN ('    };')
    179.  
    180. END.
    181.  
     

    Вложения:

    Последнее редактирование: 12 июн 2026 в 22:11
  7. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    667
  8. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    34
    Собрал сишный исходник с помощью gcc.
    Код (Text):
    1. @echo off
    2. cd C:\Users\Admin\Desktop
    3. "C:\Program Files\CodeBlocks\MinGW\bin\gcc.exe" Game_v1.c -o Game.exe -lgdi32 -luser32 -lkernel32 -mwindows -Os -s -ffunction-sections -fdata-sections -Wl,--gc-sections
    4. if %errorlevel% == 0 (
    5.     echo Success! Running game...
    6.     Game.exe
    7. ) else (
    8.     echo Compilation failed!
    9. )
    10. pause
    Выхлоп: 25,5 КБ.

    Тот же самый код на pascal: 23,5 КБ.

    --- --

    Подозреваю, что есть какие то еще магические способы компиляции, уменьшающие размер .ехе, без танцев с бубном.
     

    Вложения:

    • Game_v1.rar
      Размер файла:
      30,8 КБ
      Просмотров:
      14
    Последнее редактирование: 13 июн 2026 в 03:20
  9. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    360
    Ahimov, нет.. я там не зареган.
     
  10. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.395
    Вместо сбора секций можно было LTO обойтись, не? (-flto) Ну и говоря о еще меньшем размере, Цэ/Плюсы то будет попроще без стандартных библиотек собрать, чем Паскали.
     
  11. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    34
    Ехе собирался батником который сгенерировал дипсик.
    Интересно можно ли изменением .bat файла собрать .ехе меньшего размера.
    Код (Text):
    1. @echo off
    2. cd C:\Users\Admin\Desktop
    3. "C:\Program Files\CodeBlocks\MinGW\bin\gcc.exe" Game_v1.c -o Game.exe -lgdi32 -luser32 -lkernel32 -mwindows -Os -s -ffunction-sections -fdata-sections -Wl,--gc-sections
    4. if %errorlevel% == 0 (
    5.     echo Success! Running game...
    6.     Game.exe
    7. ) else (
    8.     echo Compilation failed!
    9. )
    10. pause
    Какое-то очень всратое впечатление о си. Там где в паскале достаточно в uses указать нужные файлы,
    в си нужно сразу 10 вещей делать. Нужно гадать с какими параметрами собирать исходник. Это для удобства сделано? :)
    --- Сообщение объединено, 13 июн 2026 в 09:45 ---
    Ехе стал меньше на 0,5 кб. Вместо 25,5 КБ -> 25 КБ.

    Думал что на си будут какие то радикальные изменения, типа ехе в 7 КБ, но не 25 же.
     
    Последнее редактирование: 13 июн 2026 в 09:50
  12. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    667
    Tech,

    Размеры двух яп нельзя сравнить, так си использует импорт системных длл. Например для печати дробных чисел вызывается процедура из ртл, в нэйтив нет возможности печати математики(printf() не полноценна). В паскале это возможно билдится сразу, сравнение не корректно.

    На счет мин размера есть тема, там выполнен анализ загрузчика.

    дипсик сломали, из за перегрузки серверов выключили доступ в сети и файлы :dntknw:
     
  13. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    34
    Бред.

    По твоему это релевантно: переписать .бат файл чтобы уменьшить размер.
     
  14. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    667
    Tech,

    Попробуй распечатать 1/3, поймешь о чем я. Может на счет билда не точно, я не знаю как у дельфи. Можешь проверить.

    Системная ntdll.Xprintf не поддерживает /e, f
     
  15. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    34
    Ты недавно говорил:
    Просто перепиши это:
    Чтобы был норм эффект. Для человека который все до инструкций понимает, это вообще не проблема. Просто батник, без всякой умной херни про ядро и драйвера.
     
  16. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    667
    Tech,

    Так ты делаешь чепуху, не рассматривая содержимое файлов, сравниваешь размер. Может там вообще область без ничего в 20кб.

    Сишное приложение завязано на системные длл, соотв. оно в любом случае меньше размером, тк часть кода уже встроена в систему. Открывай дизом и смотри содержимое.

    > Просто перепиши это:

    Это не работает на андроиде, параметры описаны в спецификации. Если лень читать, спроси у бота. Мне за тебя это делать не интересно.
     
  17. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.395
    Минимальный размер хеллоу ворлда будет 4кб без объединения секций.
    --- Сообщение объединено, 13 июн 2026 в 15:34 ---
    Код (C):
    1.  
    2. #include <windows.h>
    3. void EntryPoint() {
    4.     MessageBoxA(NULL, "Hello World", "Hello World", MB_OK);
    5.     ExitProcess(0);
    6. }
    7.  
    Код (Text):
    1.  
    2. x86_64-w64-mingw32-gcc -o ./test.exe -O3 -Os -flto -nostdlib -s ./test.c -eEntryPoint -lkernel32 -luser32
    3. wine ./test.exe
    4.  
    Код (Text):
    1.  
    2. > ls -l
    3. -rw-r--r-- 1 user user  124 июн 13 15:26 test.c
    4. -rwxr-xr-x 1 user user 3584 июн 13 15:31 test.exe
    5. -rw-r--r-- 1 user user  101 июн 13 15:30 test.sh
    6.  
     
  18. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    4.259
  19. CaptainObvious

    CaptainObvious Member

    Публикаций:
    0
    Регистрация:
    18 янв 2024
    Сообщения:
    111
    У него есть исходник. Зачем ему еще открывать дизом?
    Имхо, он и без тебя школьника знает, что параметры описаны в спецификации.
     
  20. q2e74

    q2e74 Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    1.027
    у вас исходник(не знаю про какой именно вы говорите) проходит линковщик и загрузчик. а возможно и компилятор. поэтому исходик хорошо, но реальность она не всегда в исходнике.