1. Pascal / Говнокод #17455

    +95

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    program Yields;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    uses
      System.Yield in 'System.Yield.pas';
    
    
    procedure ShittyRec(Yield: TYield<Integer>; depth, par1, par2: integer);
    var
      i: integer;
    begin
      Yield(par1+par2);
      if depth>100 then
        exit;
      for i := 0 to 99 do
      begin
        par2 := par2*65537+1;
        ShittyRec(Yield, depth+1, par1*(i+1)+par2, par2);
      end
    end;
    
    function GetNextShittyInt: TYieldEnumerable<Integer>;
    begin
      Result := TYieldEnumerable<Integer>.Create(
        procedure(Yield: TYield<Integer>)
        begin
          Yield(0);
          ShittyRec(Yield, 0, 1, 2);
        end);
    end;
    
    var
      i: Integer;
    begin
      for i in GetNextShittyInt do
      begin
        Writeln(i);
      end;
      Readln;
    end.

    Запостил: LispGovno, 16 Января 2015

    Комментарии (45) RSS

    • Привет, Тарас!
      Ответить
      • Кстати я автор исходного кода(не поста), не тарас.
        Вообще мне правда порвали шаблон Fiberы, на которых это сделано. Корутины из времен WinNT3.51, с минимальным оверхедом на переключение потока (я правда его не тестил, но по описанию он меньше чем у обычных потоков т.к. планировщик в нем не участвует и даже TLS не надо переключать).
        Ответить
        • > минимальным оверхедом на переключение
          Т.е. хардкорный ассемблер, как в boost::coroutine?
          Ответить
          • В мсдн говорится что он минимальный. А какой он на самом деле я не мерял, но WinNT ведь не на тормозных крестах писали.
            Ответить
            • А, дык там всего лишь виндовые файберы (CreateFiber() и ко), а не свой хардкор на асме? Бустовские рвут их как тузик грелку.

              http://www.boost.org/doc/libs/1_57_0/libs/context/doc/html/context/performance.html
              Ответить
              • P.S. Эээ, а куда цифры из таблицы пропали? :)
                Ответить
                • Наверное там нули!
                  Ответить
                  • undefined ns / undefined cycles
                    Ответить
                  • От нас скрывают... Правительство. Прикиньте панику в народе: Многоядерные процессоры не нужны. Зеленые потоки файберов дают буст овердевятсот. А нам впаривают корпорации эти свои девайсы за большие бабки. Сразу банкротства по всему миру и паника.
                    Ответить
                    • Файберы работают быстрее, и им стало стыдно?
                      Ответить
                      • Боятся свержения правительства. Пост обновлен.
                        Ответить
                      • Без сохранения контекста плавучки и расширений цпу буст всяко быстрее. Но вот внезапно файберы могут сохранять расширения и плавучку по требованию (лениво). То есть не сохранять и тут они могут получается выиграть (если расширения и плавучка используются редко) у буст-контекста, тк тот всё всегда сохраняет, если не указать обратное.
                        Ответить
                        • Что значит лениво? Как они узнают используется или нет и почему об этом не может также узнать буст?
                          Ответить
                          • Прерывание происходит. В общем случае не быстро, но если не часто, то быстро. А буст не ос и осефичи не юзает
                            Ответить
                            • > Прерывание происходит.
                              Можно поподробнее (или даже ссылочку)?
                              Ответить
                              • Modern CPUs provide an option to disable the ability to execute any FP instructions. When the CPU attempts to execute an FP instruction, an exception is posted and operating system starts processing the 'FPU was unavailable for me' handler for the executing process. This can then check and prepare the FPU for use, then restart the process at the FP instruction which posted the exception. This time FP instructions will be executed normally and not produce the 'FPU is unavailable' condition unless another process later takes the FPU.

                                http://www.netbsd.org/docs/kernel/lazyfpu.html
                                Ответить
                                • Но ведь там кроме FPU регистров есть еще и огроменные SSE'шные. Для них это тоже катит?
                                  Ответить
                                  • тебя в гугле чтоли забанили? бота чтоли заведи

                                    The FPU/MMX and SSE state could be saved and reloaded, but the CPU can also be tricked into generating an exception the first time that an FPU/MMX or SSE instruction is used by copying the hardware context switch mechanism (setting the TS flag in CR0).

                                    http://wiki.osdev.org/Context_Switching
                                    Ответить
                                    • > тебя в гугле чтоли забанили
                                      Я ленивый пиздюк.
                                      Ответить
                                      • Зачем так плохо к себе относится? Посмотри мотивирующие фильмы
                                        Ответить
    • Паскаль с шаблонами рвёт мне шаблон.
      Ответить
      • А замыкание в строках 27-31 уже нормально?
        Ответить
        • Замыкание в паскале это как регулярные выражения в фортране
          Ответить
          • Регулярные выражения можно реализовать функциями, а для замыканий нужна поддержка компилятора.
            Ответить
            • >>Регулярные выражения можно реализовать функциями
              А вот perl, ruby и местами JS так не думает
              Ответить
      • Паскаль с елдами o_O
        Ответить
        • Елды были ещё в WinAPI для 3.x:
          {*******************************************************}
          {                                                       }
          {       Turbo Pascal for Windows Run-time Library       }
          {       Windows API Interface Unit                      }
          {                                                       }
          {       Copyright (c) 1991 Borland International        }
          {                                                       }
          {*******************************************************}
          
          unit WinProcs;
          
          interface
          
          uses WinTypes;
          
          ...
          
          function Yield: Bool;
          
          ...
          
          implementation
          
          ...
          
          function Yield;				external 'KERNEL' index 29;
          Ответить
          • Держу пари что елда в в311 была не ради красоты написания асинхронного кода, а ввиду кооперативной многозадачности. Идея-то та же самая: "если ты знаешь что внещнего ресурса ждать долго -- скжаи yield и дай поработать другим", просто причина не в желании не плодить потоки, а в архитектуре ОС.
            Ответить
            • Да в общем-то она и сейчас есть. Можно остаток таймслайса другим процессам отдать, если самому уже делать нечего.

              P.S. Но лучше для этого воткнуть какое-нибудь ожидание или блокирующую операцию. Эффект будет тот же, но тред не будут будить без повода.
              Ответить
              • А можно не остаток, а целое ядро на 27 дней.
                Ответить
              • В не реалтайм системе с вытесняющей многозадачностью Вам должно быть похуй на другие процессы. Разумный эгоизм же. Пусть у шедулера голова болит.
                Ответить
                • Ну так то да. В правильной проге мы либо что-то делаем (и планировщик отберет управление сам), либо чего-то ждем (и на это время отдаём управление).

                  Yield нужен разве что для мягкого busy wait'а (не будем обсуждать его нинужность):
                  while (!cond)
                      Yield();
                  Ответить
                  • > не будем обсуждать его нинужность
                    а он нужен при реализации критических секций или при реализации локфри методов
                    Ответить
                    • > критических секций
                      Не особо, если честно. Внутри спинлока не ставят Yield (т.к. с тем же успехом можно сразу уйти в wait), а после неудачного спинлока будет уже wait.

                      > бизивейтах
                      Мы сейчас не о обычном бизивейте (аля спинлок), а о мягком, который я показал выше.
                      Ответить
                      • согласен про крит секции. я чувствую себя униженным. Пойду продам с молотка аккаунт BormandGovno
                        Ответить
                  • Бизивейты в юзер моде как мне кажется не используют. Вот в ядерном спейсе бывают спинлоки всякие, но там наврядли елдят.
                    Ответить
                    • одна только часть реализации критических секций реализована в юзермоде на бизивейтах. И тв не поверишь! Даже шаред птр на бизевейтах.
                      Ответить
            • > Держу пари что елда в в311 была не ради красоты написания асинхронного кода
              Капитан, улыбка сделала бы ваше лицо красивее. Хотя и морщинистее.
              Ответить
              • "Я всегда говорю очевидные вещи, и потому я всегда прав" (c)
                Ответить
                • А те вещи, что ты не видишь очами - уже не говоришь?
                  Ответить
                  • Если я чего-то не вижу то этого не существует
                    Ответить
                    • Весь мир - это сон анонимуса.
                      Ответить
                      • Притом достаточно влажный.
                        В монаду IO заверни или останови для сборки мусора.
                        Ответить
        • > Паскаль с елдами o_O
          Похоже твой смайлик демонстрирует нам лицо подопытного:
          Паскаль трёт немного эбонитовую палочку, а потом вставляет подопотному свою елду.
          Ответить

    Добавить комментарий