1. Куча / Говнокод #26984

    +1

    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
    pub struct Vec { x: u32, y: u32, z: u32, }
    
    pub extern "C" fn sum_c(a: &Vec, b: &Vec) -> Vec {
        return Vec {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
    }
    
    pub fn sum_rust(a: &Vec, b: &Vec) -> Vec {
        return Vec {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
    }
    
    Выхлоп:
    
    example::sum_c:
            mov     eax, dword ptr [rsi]
            add     eax, dword ptr [rdi]
            mov     ecx, dword ptr [rsi + 4]
            add     ecx, dword ptr [rdi + 4]
            mov     edx, dword ptr [rsi + 8]
            add     edx, dword ptr [rdi + 8]
            shl     rcx, 32
            or      rax, rcx
            ret
    
    example::sum_rust:
            mov     ecx, dword ptr [rdx]
            mov     r8d, dword ptr [rdx + 4]
            add     ecx, dword ptr [rsi]
            add     r8d, dword ptr [rsi + 4]
            mov     edx, dword ptr [rdx + 8]
            add     edx, dword ptr [rsi + 8]
            mov     rax, rdi
            mov     dword ptr [rdi], ecx
            mov     dword ptr [rdi + 4], r8d
            mov     dword ptr [rdi + 8], edx
            ret

    «Дак йаже как Сишка!», «Даёшь пuтушатню в Ядро!»
    https://godbolt.org/z/Tcnz75
    rustc 1.46 (latest)

    Запостил: 3.14159265, 28 Сентября 2020

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

    • Хотите ускорить свои программы? Просто добавьте к вашим функциям extern "C" («йаже как Сишка!»)
      Ответить
    • Хм, у растишки какое-то своё соглашение о вызовах? Варианта с rdx:rax для мелких структур нету?
      Ответить
      • Да.

        Притом что эти кретины до сих пор не имеют стабильного ABI. И принципиально на том стоят.

        https://people.gnome.org/~federico/blog/rust-stable-abi.html#rust_does_not_have_a_stable_abi

        >By default indeed it doesn't, because the compiler team wants to have the freedom to change the data layout and Rust-to-Rust calling conventions, often for performance reasons, at any time.

        Кокой пирфоманс )))

        >But we only have a single stable ABI anyway
        >And that is the C ABI.

        Ещё раз:
        >Summary of ABI so far
        It is one's decision to export a stable C ABI from a Rust library. There is some awkwardness in how types are laid out in C, because the Rust type system is richer, but things can be made to work well with a little thought. Certainly no more thought than the burden of designing and maintaining a stable API/ABI in plain C.

        Но при этом постоянно сливаются стабильному сишному ABI.
        Ответить
        • > Rust type system is richer

          Эм, а что у них там такое есть в языке, что нельзя как няшную структуру представить?
          Ответить
          • Хз. Кто бы меня просветил. Может туплы какие.

            Не удивлюсь что в итоге будет очередной обсёр с ненужной питушнёй.
            Ответить
            • Ну вот в «Delphi» и в «FPC» бывают «open arrays», когда вместе с массивом передаётся его длина. В «Расте» ничего подобного нет?
              Ответить
              • Оказывается эта питушня сделана не по причине какой-то навороченности раста, но из-за его говняности.

                А именно чтобы не так тупили итераторы и прочие говноабстракции.

                The reason Rust doesn't have a defined ABI is basically that it wouldn't buy the same benefits it does in C. Specifying an ABI requires a lot of per-platform work (which the C community has already done), and, because of the importance of cross-crate inlining (all generic functions get inlined into call-sites by default), would not be sufficient to provide the benefit of in-place library updates. If you rewrite generic code in libfoo, and libbar depends on it, you can't get around recompiling libbar.

                This is basically because Rust is a higher-level language where you use iterators, iterator adaptors, and higher-order functions in the course of writing libraries and applications. In C, you would manually inline things like iteration, writing for loops and populating intermediate data structures yourself. In Rust, this is something that can be factored out into libraries, but that means your code's meaning depends more deeply on the meaning of library code. To optimize away these abstractions and provide good performance, the compiler needs to inspect and make decisions based on library source code when compiling code that calls it. To permit efficiency, Rust basically has to be compiled from leaf dependencies upward.
                Ответить
                • Да ладно, в крестах та же проблема. Просто все уже привыкли к шилу в жопе.
                  Ответить
                  • В крестах есть pimpl.
                    Ответить
                    • Ну тут же речь о дженериках, а не обычных методах. Для шаблонов в крестах никакого пимпла быть не может.
                      Ответить
                      • Думаю дело не только в женериках, а в целом ненужных абстракциях для «безопасности».

                        Там где можно было передать обычный массив/указатель, нужно городить итераторы (не обязательно на женериках).

                        И невозможно защититься от слома ABI. То есть нужно постоянно перекомпилировать не только свой crate, но и все крейты от которых он зависит. Причём как в случае изменения кода, так и в случае изменения ABI.

                        А компиляция в rust по ощущениям не быстрее крестовой.
                        Ответить
                        • Да в крестах абсолютно та же хуйня. Именно из-за этого в стандарт не могут внести многие интересные изменения - боятся сломать ABI стандартной либы, на которое и так никто особо не полагается ибо были прецеденты.

                          > от которых он зависит

                          Точно не наоборот? Все крейты, которые от него зависят, имхо. Т.к. они натянули себе дженериков из прошлой версии.
                          Ответить
                          • >Все крейты, которые от него зависят.
                            Да, оговорился.
                            Ответить
                            • Не хотят брать на себя ответственность. Потом ведь хуй что поменяешь в стандартной либе если кто-то завяжется на ABI. А так - поворчат что ABI нету да успокоятся.
                              Ответить
                              • Мда. А народ (я в том числе) ещё ругали С++.

                                После бездн, которые являет rust очевидно какой объём титанической неблагодарной работы делает Комитет и компиляторщики.

                                >хуй что поменяешь в стандартной либе если кто-то завяжется на ABI
                                Думаю им надо просто линковать в зависимости от флага
                                -std=c++11
                                Какие проблемы?

                                Ведь он уже и так влияет на многие вещи. Кмк, можно написать программу, которая с -std=c89 и -std=c99 вернёт разный результат.

                                У крестов стандарт раз в 5 лет. И каждый из них чётко специфицирован. А у пuтушатни это уже 46ой релиз.
                                Ответить
                                • > какие проблемы

                                  Тебе хочется таскать и поддерживать N версий стандартной либы параллельно? Для каждого режима нужна будет своя.

                                  Не ифдефами же её обмазывать, в конце-концов. С ифдефами вообще треш лютый будет, там и так то читать сложно.
                                  Ответить
                                  • С релизом стандарта раз в 5 лет их будет максимум 2 штуки: старая и новая.

                                    Кому-то сейчас нужен С++ 2003?

                                    Edit: хотя да, это в Луникс мире, где у всех есть сырцы и постоянно новые дистры. На виндах с каким-нибудь говном под msvcrt2003 это действительно проблема
                                    Ответить
                                    • Нет. Но ты ведь ABI сломал и с c++11 ABI я какую-нибудь проприетарную либу не смогу прилинковать. Ибо она у меня только под c++03 ABI.

                                      Не меняя ABI в стандарте они дают мне возможность прыгнуть на новые кресты без пересборки старых либ. Ну если разрабы стандартной либы сами что-то не сломают.
                                      Ответить
                                      • > какую-нибудь проприетарную либу не смогу прилинковать. Ибо она у меня только под c++03 ABI.

                                        Согласен. Я выше уже сам допёр.
                                        ПРОПРИЕТАРОПРОБЛЕМЫ
                                        Ответить
                                      • >Не меняя ABI в стандарте они дают мне возможность прыгнуть на новые кресты без пересборки старых либ.

                                        И тем не менее в виндах постоянно ситуация что нужно иметь установленными рантаймы msvcrt2003, msvcrt2005, msvcrt2008, msvcrt2013, msvcrt2015, итд.
                                        Ответить
                                    • > луникс мире

                                      Вот кстати, кто бы говорил про стабильное ABI. У прыщеядра то его нет. Там даже API для дров плавает.
                                      Ответить
                                • Ну потому что кресты - старый, зрелый язык. Ему можно раз в пять лет. Я думаю по началу Бьярни точно так же хуярил по 46 релизов в день.
                                  Ответить
                                • > У крестов стандарт раз в 5 лет. И каждый из них чётко специфицирован. А у пuтушатни это уже 46ой релиз.

                                  Calling conversion (ведь вы тут о нем толкуете?) в стандарте крестопараши вообще нихуя не специфицирован. Т.е. всякая херня типа thiscall, fastcall и прочая такая дрисня - это все компиляторостроители для себя решают. Аналогично, крестопарашный стандарт нихуя не специфицирует относительно механизма обработки исключений (в винде вообще какая-то дичайшая срань под названием SEH сделана) и еще нихуя не сказано про то, как манглится всякая херня перегруженная.
                                  Ответить
                                • Ну и насчет четко специфицированного крестопарашного стандарта я тоже писал, и даже недавно скидывал в тему цитату Дейкстры https://govnokod.ru/26958#comment575963

                                  Я очень сомневаюсь в том, что человечеству под силу четко специфицировать такую ебучую переусложненную костыльную дрисню с кучей UB, как «С++».
                                  Ответить
                                  • > Я очень сомневаюсь в том, что человечеству под силу четко специфицировать такую ебучую переусложненную костыльную дрисню с кучей UB, как «С++».

                                    Привыкай
                                    Ответить
              • Иными словами borrow checker просто не даст сделать нормальные, простые API.

                Без нагноения вокруг вызова туч обёрточек, итераторов и прочих абстракций. Чтобы всё было «безопасно».

                А если похерить это всё и писать нормально, тогда смысл rust пропадает.

                И это действительно ОГРОМНАЯ проблема:

                http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-in-c
                >Currently there is 11 THOUSAND lines of Rust in wlroots-rs. All of this code is just wrapper code, it doesn’t do anything but memory management.
                >This isn’t just repeated code either, I defined a very complicated and ugly macro to try to make it easier.

                >This wrapper code doesn’t cover even half of the API surface of wlroots. It’s exhausting writing wlroots-rs code, memory management is constantly on my mind because that’s the whole purpose of the library. It’s a very boring problem and it’s always at odds with usability - see the motivation for the escape from callback hell described above.

                >To do all of this, and then go write Way Cooler, already a big undertaking, is too much for me to commit to. When the benefit at the end of the day is just so I don’t have to write C, that doesn’t really make it worth it. If I got this out of the box by simply linking to the library, like I can in C++, then it would be much more tenable.

                >I can always just use unsafe bindings to wlroots, just like I would with any other language. However, the entire point of Rust is that it’s safe. Doing that is not an option because at that point you lose the entire benefit of the language.
                Ответить
                • И чтобы их говняные переусложнённые API не так сливали Сишке, они оставляют за собой возможность перманентных изменений в ABI.
                  Ответить
            • Структура и есть тупла. Или наоборот, не помню уже, в моём питушином моске не помещается столько терминов.
              Ответить
          • А что у них такого есть в языке, чего нельзя представить как массив байт.

            tsarified
            Ответить
    • Какой интероп с сями удобный)

      следующим шагом интероп у раста нужно сделать разным в зависимости от версии компилятора
      Ответить
      • > следующим шагом интероп у раста нужно сделать разным в зависимости от версии компилятора
        Так и есть )))

        Просто ору дичайше.

        Лалки собрались пихать в ядро язык который:
        а) абсолютно неспецифицирован
        б) привязан к конкретной компиляторной платформе написанной на С++
        в) для него невозможно произвести раскрутку компилятора
        г) не имеющий стабильного ABI (тот что есть ворованный у Сишки)
        Ответить
        • кристушки же вроде так и живут: нужно всё собирать одний версией компилятора, а еще бывает несколько разных рантаймов
          Ответить
        • Раскрутку компилятора?
          Ответить
          • Да. Она же бутсраппинг.

            Из вчерашней статьи:

            First of all, bootstrapping process is laughably bad. I realize that it’s never too easy but if you call yourself a systems programming language you should be able to bootstrap a compiler in a sane amount of steps. For instance, IIRC Guix has the following bootstrapping process for C compiler: simple C complier in Scheme (for which you can often write an implementation in assembly by hand) compiles TCC, TCC compiles GCC 2.95, GCC 2.95 compiles GCC 3.7, GCC 3.7 compiles GCC 4.9. For rustc you should either start with the original compiler written in OCaml and compile every following version with the previous one (i.e. 1.17 with 1.16) or cheat by using mrustc written in C++ which can compile Rust 1.19 or 1.29 (without borrow checks), then compile 1.30 with 1.29, 1.31 with 1.30 etc etc. The problem here is that you cannot skip versions and e.g. compile rustc 1.46 with rustc 1.36 (I’d be happy to learn that I’m wrong). IMO you should have maybe an ineffective compiler but written in a dialect that much older compiler should understand i.e. rustc 1.0 should be able to compile a compiler for 1.10, which can be used to compile 1.20 and so forth. Of course it’s a huge waste of resources for rather theoretical problem but it may prove beneficial for compiler design itself.

            Учитывая время компиляции rustc раскрутка до 1.46 будет длиться целую вечность.
            Ответить
            • Ну хули делать. Тут или страдать и писать весь конпелятор на прошлогоднем диалекте. Или вот такая вот цепочка.

              Я бы не считал это прям уж серьёзной проблемой, бутстрап с нуля - это всё-таки маргинальный кейс. Главное чтобы он вообще был.

              > вечность

              Там поди ещё и разные версии llvm понадобятся по ходу развития. Не факт, что вся история раста была на совместимых версиях llvm.
              Ответить
              • >Я бы не считал это прям уж серьёзной проблемой
                >бутстрап с нуля - это всё-таки маргинальный кейс

                Всё верно, если бы не нюанс который меняет вообще ВСЁ.

                rust постоянно позиционируется как язык системного программированния! «йаже как Сишка»

                > With direct access to hardware and memory, Rust is an ideal language for embedded and bare-metal development.
                > You can write extremely low-level code, such as operating system kernels or microcontroller applications.
                Ответить
                • > позиционируется как язык системного программирования

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

                    Так-то я портану минимальную питушню, собрал с ней питуха 1.0 и радуюсь жизни.

                    А так пока кому-то в LLVM влом чинить багу для какой-то платформы, rust будет сосать на ней хуйца.
                    Ответить
                    • Дык кто сейчас лезет на новую платформу и что-то там хуярит снуля каменным топором? Даже с гцц никто так делать не будет, тупо кросс соберут на какой-то из уже работающих платформ.

                      Про LLVM согласен. Но это не из-за бустрапа, это просто из-за использования внешнего компонента.
                      Ответить
                    • З.Ы. А, понял в чём проблема. Тогда такая платформа навсегда останется завязанной на
                      другую, с которой кросс собирали. Ибо в старых llvm/rust она не поддерживалась.

                      Т.е., к примеру, arm нельзя будет бустрапнуть без тачки с x86_64.

                      Да, это полная жопа.
                      Ответить
                      • Да это же готовый сюжет stein's;gate 3:0: в будущем из далёкого будущего прилетит Джон Титор, чтобы найти в будущем последний проц забытой архитектуры x86_64, чтобы забутстрапить им раст, т.к. какой-то долбоёб из CERN в настоящем написал на нём внутреннюю гостевуху.
                        Ответить
                        • просто переписать гостевуху нельзя, потому что тогда не будет сюжета?
                          Ответить
                          • >просто переписать гостевуху нельзя
                            >CERN

                            К 27 веку, после 2х ядерных зим и одного каскадного резонанса человечество усвоит простую истину.
                            Работает — не трогай!
                            Ответить
                            • угу

                              и даже после двух ядерных зим в гостевухе на расте будут вскукареки про пхп и нотепаде++ от ракоты
                              Ответить
                        • А потом возвращаться в прошлое и передавать себе собранные бинари раста. Потому что у него есть только 5 минут, а собрать надо цепочку из десятка тысяч версий.
                          Ответить
                          • >собрать надо цепочку из десятка тысяч версий

                            На тормозном микроко-ко-контроллере.
                            Ответить
                          • ...но в прошлом github репу Rust взломали агенты CERN, и начали менять ABI "для перфоманса".
                            ГГ пришлось войти во временную петлю, в которой он десять тысяч раз должен был пропатчить код всех промежуточных версий компилятора. Ибо если бы ждал чуть дольше, церновцы бы изменили синтаксис и семантику языка настолько, что это вызвало бы расхождение временных линий.
                            Ответить
                            • > взломали агенты CERN

                              Случайно откопав её в арктике?
                              Ответить
                              • Не, в арктике только потом уже случайно закомиченный приватный ключ к Skynet откопали. Доступ к растишке они получили, создав с помощью БАК особые частицы, находящуюся в суперпозиции 10.000 гендеров, и облучив ими своих агентов. Система была запрограммирована не препятствовать настолько разнообразным индивидуумам.
                                Ответить
                            • > и начали менять ABI "для перфоманса"
                              > и облучив ими своих агентов.

                              То есть нынешний хайп пuтушатни тщательно расчитаный хитрый план сил Зла?
                              Облучённые CERNом клоуны бегают по хабрахабрам и пишут хвалебные статейки.
                              Ответить
                • З.Ы. Гентушники, конечно, будут плакать.
                  Ответить
                  • А ведь Царь же гентушок!!!

                    Теперь понятно, почему он один из первых стал бить тревогу.
                    Ответить
              • https://docs.rust-embedded.org/faq.html

                (When) will Rust support the AVR architecture?
                As of 2018-09-19 the official Rust compiler, rustc, relies on LLVM for generating machine code. It's a requirement that LLVM supports an architecture for rustc to support it.

                LLVM does support the AVR architecture but the AVR backend has bugs that prevent it from being enabled in rustc. In particular, the AVR backend should be able to compile the core crate without hitting any LLVM assertion before it's enabled in rustc. A likely outdated list of LLVM bugs that need to be fixed can be found in the issue tracker of the rust-avr fork of rustc.

                TL;DR rustc will support the AVR architecture when the LLVM backend is relatively bug free. As LLVM is a project independent of the Rust project we can't give you any estimate on when that might happen.


                АХАХАХАХА
                Ответить
      • https://www.reddit.com/r/rust/comments/a1thmg/a_little_thought_on_a_rust_abi/

        So I know a binary stability is not a goal right now, even an anti-goal. I don't propose introducing a versioned ABI or something like that, because I've seen that the core developers are not really fond of this topic at all.

        But isn't it a shame that even if a library author wants to provide a stable ABI, he cannot? Of course it is possible to define interoperability of structs and functions with C, but don't you lose some of rust's (best) features? Would it not be nice to be able to export rust specific behaviour, too?
        Ответить
    • Получаются разные кокококоллкокококонвеншны.

      В режиме «extern "C"» у нас два аргумента: rsi указывает на одну структуру, rdi — на другую.

      eax = a.x + b.x;
      ecx = a.y + b.y;
      edx = a.z + b.z;

      А вот дальше после сдвига и логического «ИЛИ» в половинках rax у нас лежат две суммы (a.x + b.x и a.y + b.y), а в младшей половинке rdx лежит оставшаяся сумма (a.z + b.z). Итого пара (rdx, rax) используется для возвращения структуры, помещающейся в 128 бит.

      В режиме питушни у нас тоже два аргумента, тоже указатели на структуры, но приходят они в регистрах rdx и rsi, а для разврата используется не пара (rdx, rax), а заранее выделенное вызывающим кодом место, куда указывает третий аргумент (rdi). Ещё и этот третий аргумент зачем-то копируется в rax. Фактически функция возвращает свой неявный аргумент.
      Ответить
      • Да. Всё верно.

        >Ещё и этот третий аргумент зачем-то копируется в rax
        В rax отдаём, то что развращается из return.
        Ответить
        • Т. е. (в псевдокоде) растишная версия эквивалентна чему-то такому:
          pub fn sum_rust(result: &Vec, a: &Vec, b: &Vec) -> Vec {
              *result = Vec {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
              return result;
          }
          Ответить
          • Скорее всего.
            Там же под капотом педерача всяких gowership (по сути мув-сёмантика из С++).

            https://doc.rust-lang.org/rust-by-example/scope/move.html
            >When doing assignments (let x = y) or passing function arguments by value (foo(x)), the ownership of the resources is transferred. In Rust-speak, this is known as a move.
            Ответить
      • В няшной для больших структур примерно такой же конвеншен - указатель на буфер в первом аргументе. Но вот eax там вроде не заполняют, вызывающий код и так знает где у него буфер.
        Ответить
        • «Трупопаскаль» так же поступал, когда нужно вернуть строку.

          Зачем в «Растишке» придумали заполнять eax, я не понимаю. Это же только прогрев процессора. Неужели бывают реальные примеры, когда нужно возвращать не тот буфер, который передали?
          Ответить
        • показать все, что скрытоvanished
          Ответить
    • Для сравнения, кресты:
      #include <cstdint>
      
      struct Vec { uint32_t x; uint32_t y; uint32_t z; };
      
      Vec sum(Vec& a, Vec& b)
      {
          return Vec {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
      }
      
      sum(Vec&, Vec&):
              movq    xmm0, QWORD PTR [rdi]
              movq    xmm1, QWORD PTR [rsi]
              mov     edx, DWORD PTR [rsi+8]
              add     edx, DWORD PTR [rdi+8]
              paddd   xmm0, xmm1
              movq    rax, xmm0
              ret

      https://godbolt.org/z/zcjaEY
      Ответить
      • А на "PHP" это как будет выглядеть?
        Ответить
        • Нетипизированный вариант:
          <?php
          
          function sum(&$a, &$b)
          {
              return ['x' => $a['x'] + $b['x'], 'y' => $a['y'] + $b['y'], 'z' => $a['z'] + $b['z']];
          }


          Типизированный вариант:
          <?php
          class Vec {
              public $x; // В PHP 7.4 тут ещё можно указать типы полей: public int $x; и т. д.
              public $y;
              public $z; 
              public function __construct(int $x, int $y, int $z) {
                  $this->x = $x; $this->y = $y; $this->z = $z;
              }
          }; 
          
          function sum(Vec &$a, Vec &$b): Vec // Тип результата можно указать только в PHP7
          {
              return new Vec($a->x + $b->x, $a->y + $b->y, $a->z + $b->z);
          }
          Ответить
      • Эм, а почему кресты лучше сишки оптимизнули? Код же точно такой же во фронтенде. Другой конпелятор?
        Ответить
        • Я сам удивился. Оказалось это gcc такой хитрый.

          Да-да, ведь rust прибит гвоздями к LLVM.
          Шланг:
          sum(Vec&, Vec&):                         # @sum(Vec&, Vec&)
                  mov     eax, dword ptr [rsi]
                  add     eax, dword ptr [rdi]
                  mov     ecx, dword ptr [rsi + 4]
                  add     ecx, dword ptr [rdi + 4]
                  mov     edx, dword ptr [rsi + 8]
                  add     edx, dword ptr [rdi + 8]
                  shl     rcx, 32
                  or      rax, rcx
                  ret
          Ответить
          • Вот кстати, тут бы как раз ABI поменять...
            sum:
                paddd xmm0, xmm1
                ret
            Ответить
            • Да. Я вот хотел сказать что питушня какая-то неудобная.

              Впрочем это лолжно решиться во время lto/инлайна.
              Ответить
            • Хотя не. Фигня какая-то.
              Vec sum1(Vec a, Vec b, Vec c, Vec d){
                  return sum(sum(sum(a,b),c),d);
              }
              
              sum1(Vec, Vec, Vec, Vec):
                      mov     r10, rdx
                      movq    xmm2, r8
                      movq    xmm3, rdi
                      add     esi, ecx
                      movq    xmm0, QWORD PTR [rsp+8]
                      movq    xmm1, r10
                      lea     edx, [rsi+r9]
                      add     edx, DWORD PTR [rsp+16]
                      paddd   xmm1, xmm3
                      paddd   xmm0, xmm2
                      paddd   xmm0, xmm1
                      movq    rax, xmm0
                      ret
              Ответить
              • Попробуй четырёхмерные вектора. Может с ними лучше будет.
                Ответить
                • Хуйня, хотя padd один.
                  sum:
                          mov     QWORD PTR [rsp-40], rdi
                          mov     QWORD PTR [rsp-32], rsi
                          movdqa  xmm0, XMMWORD PTR [rsp-40]
                          mov     QWORD PTR [rsp-24], rdx
                          mov     QWORD PTR [rsp-16], rcx
                          paddd   xmm0, XMMWORD PTR [rsp-24]
                          movaps  XMMWORD PTR [rsp-40], xmm0
                          mov     rax, QWORD PTR [rsp-40]
                          mov     rdx, QWORD PTR [rsp-32]
                          ret

                  Надо с __attribute__((fastcall)) попробовать или как там в x64.
                  Ответить
                  • Ну при инлайне должно уйти, кстати. Если конпелятор целиком массивы увидит, не распидорашенные на пары аргументов.
                    Ответить
                • #include "stdint.h"
                  
                  typedef struct Vec { uint32_t x; uint32_t y; uint32_t z; uint32_t q; } Vec;
                  
                  __attribute__((ms_abi))
                   Vec sum(Vec a, Vec b){
                       Vec v = {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z, q:a.q+b.q };
                       return v;
                  } 
                  
                  sum(Vec, Vec):
                          movdqu  xmm0, XMMWORD PTR [rdx]
                          movdqu  xmm1, XMMWORD PTR [r8]
                          mov     rax, rcx
                          paddd   xmm0, xmm1
                          movups  XMMWORD PTR [rcx], xmm0
                          ret

                  Лучшее что удалось сделать это поставить ms_abi
                  Ответить
                  • > mov rax, rcx

                    Хм, и тут эта хуйня. Зачем? Зачем?
                    Ответить
                    • Шланг без ms_abi такое гавнище генерит )))

                      Какие-то шаффлы, анпаки, punpcklqdq.

                      Я даже постить этот пиздец не буду
                      https://godbolt.org/z/EKxdds

                      Если растушатня даст такой же выперд (а в реальности скорее ещё хуже), то нах она нужна?
                      Ответить
                      • Еба-а-ать…
                        movdqa  xmm0, xmmword ptr [rip + .LCPI0_0] # xmm0 = [0,4294967295,0,4294967295]

                        Блядь, а ЭТО что за хуйня?!
                        Ответить
                        • Эм, просто загрузка переменной констант с масочками.
                          LCPI0_0
                          Даже сам код от этого охуел.
                          Ответить
                          • > с масочками
                            Охуеть. Чтобы сложить четыре вектора.
                            Ответить
                            • Кручу-верчу запутать хочу.
                              Ответить
                            • Причём если оно обосралось на таком простом примере, что LLVM сгенерит для пuтушни в реальном векторном коде?

                              Теперь понятно почему пацаны игры сторого под Винду пишут
                              Ответить
                              • Сразу видно, какое соглашение о вызовах писали пердолики-теоретики, а какое — практики-профессионалы. [/color]
                                Ответить
                                • Я не могу въехать, как ему мешает то соглашение, если я для sum2 inline написал?

                                  Нахуя такое говнище генерить-то?
                                  Ответить
                                • > Сразу видно, какое соглашение о вызовах писали пердолики-теоретики, а какое — практики-профессионалы.

                                  Да какой нахуй [/color]-то?

                                  Блять, у меня теперь багор, профессиональный.

                                  Я всю жизнь был убеждён что msabi — неэффективное говно, а шланг нормальный компилятор.

                                  Тут оказывается всё наоборот. Это sysv abi на x64 днище. И шланг говнище.
                                  Ответить
                                  • А в чём разница?

                                    У msabi используются RCX, RDX, R8, R9 или XMM0, XMM1, XMM2, XMM3. Разврат в RAX, если влезает в 64 бита, плавпитух всегда в XMM0.

                                    Структуры, влезающие в 64 бита, передаются в регистрах. Всё, что больше 64 бит, передаётся по указателю.

                                    Если результат не влезает в RAX, перед вызовом выделяем место и передаём первым аргументом указатель на него.

                                    Ещё требуется «shadow space» в 32 байта.

                                    Сохранность значений RAX, RCX, RDX, R8, R9, R10, R11 возложена на вызывающий блок.

                                    Сохранность значений RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 возложена на функцию.

                                    У sysvabi используются RDI, RSI, RDX, RCX, R8, R9 или XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7. Вернуть можно 128-битное значение в паре (RDX, RAX). Плавпитух возвращается в XMM0, XMM1.

                                    Сохранность значений RBX, RBP, R12, R13, R14, R15 возложена на функцию.

                                    Некоторые функции требуют наличия «красной зоны» в 128 байт.

                                    AL может использоваться функциями с переменным количеством аргументов.

                                    R10 может использоваться вложенными функциями.

                                    *****

                                    Итого: sysvabi может использовать в два раза больше аргументов в регистрах и возвращать 128-битные значения. Остальное — мелочи.

                                    И как это портит эффективность?
                                    Ответить
                                    • > И как это портит эффективность?
                                      Так, что питушарское sysvabi пакует 16-байтные структурки в регистры, из-за чего в векторном коде получается непередаваемое дерьмище: https://godbolt.org/z/W156M9. «GCC» с этой питушнёй справляется получше, но всё равно по сравнению с божественной лаконичностью ms_abi получается говно.
                                      Ответить
                                      • P.S. А вот на выхлоп родного «Майкрософтовского» компилятора лучше не смотреть: дерьмо весь экран зальёт.
                                        https://godbolt.org/z/sr9Y4s
                                        Ответить
                                        • Походу есть какая-то грань, после которой у конпеляторов сносит крышу и они начинают генерить код как получится, даже не пытаясь всё красиво разложить по регистрам.

                                          Маленькая функция с двумя векторами же красиво получилась, в отличие от полной.
                                          Ответить
                                        • >на выхлоп родного «Майкрософтовского» компилятора лучше не смотреть

                                          Не хватало мне ещё больших моральных травм.

                                          Если бы MSVC оказался лучше Гцц и Шланга, я бы наверное пошёл и выбросился с окна.
                                          Ответить
                                      • > Так, что питушарское sysvabi пакует 16-байтные структурки в регистры, из-за чего в векторном коде получается непередаваемое дерьмище

                                        Вот именно поэтому abi называется «vectorcall».

                                        Кстати не факт что изначально MS умел хорошо пидарасить вектора.

                                        Возможно вас также заинтересует:
                                        https://www.python.org/dev/peps/pep-0590/

                                        https://docs.microsoft.com/en-us/cpp/cpp/vectorcall?redirectedfrom=MSDN&view=vs-2019
                                        Ответить
                                    • > Итого: sysvabi может использовать в два раза больше аргументов в регистрах и возвращать 128-битные значения.

                                      Вот поэтому смотря на вопрос с этой, теоретической точки зрения, я и думал что msabi говнище.

                                      А потом я смотрю на практический выхлоп sysv и ms (https://godbolt.org/z/W156M9), и понимаю что это только в теории.
                                      Ответить
                        • показать все, что скрытоvanished
                          Ответить
                  • Именно поэтому я за «ms_abi».
                    Ответить
                    • Подтверждаю.

                      https://godbolt.org/z/W156M9
                      Ответить
                      • sum4msabi(Vec, Vec, Vec, Vec):                 # @sum4msabi(Vec, Vec, Vec, Vec)
                                mov     rax, rcx
                                mov     rcx, qword ptr [rsp + 40]
                                movdqu  xmm0, xmmword ptr [rdx]
                                movdqu  xmm1, xmmword ptr [r8]
                                paddd   xmm1, xmm0
                                movdqu  xmm0, xmmword ptr [r9]
                                paddd   xmm0, xmm1
                                movdqu  xmm1, xmmword ptr [rcx]
                                paddd   xmm1, xmm0
                                movdqu  xmmword ptr [rax], xmm1
                                ret

                        Красота!
                        Ответить
            • Забавно, что в Сишке кстати выхлоп чуть получше. Но всё-равно питушня с lea.
              #include "stdint.h"
              
              typedef struct Vec { uint32_t x; uint32_t y; uint32_t z; } Vec;
              
               Vec sum(Vec a, Vec b){
                   Vec v = {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
                   return v;
              }
              
              sum:
                      movq    xmm0, rdx
                      movq    xmm1, rdi
                      lea     edx, [rsi+rcx]
                      paddd   xmm0, xmm1
                      movq    rax, xmm0
                      ret
              Ответить
    • Вот кстати, если уж ложить хуй на ABI, то надо это делать полностью. Пусть каждая функция имеет уникальное соглашение, оптимальное для конкретного сочетания функции и точек её вызова.
      Ответить
      • Полностью согласен.

        А в итоге пuтушатня ни украсть, ни посторожить.

        У Крестов ABI будет хотя бы версионируемое.

        А в педеrustе ни ABI толком не описано, ни оптимизаций царских нет с SSE.

        46 версий хуйни, с которой потом непонятно как линковаться.
        Ответить
        • > с которой потом непонятно как линковаться

          Ну ты чо, зачем линковаться, всё будет на него переписано.
          Ответить
          • И «Линукс» на «Растишку» будут переписывать столько же лет, сколько пилят не имеющее аналогов ядро «GNU Hurd».
            Ответить
            • Именно поэтому я за форт: десяток килобайт на многозадачную ОС, конпелятор с метушнёй, интерпретатор и интерактивный шелл.
              Ответить
              • Реально многозадачную?
                Ответить
                • Не, кооперативно-многозадачную всего лишь. Yield короче.

                  Но каким-нибудь телескопом управлять пока ты пилишь что-то в консоли он вполне мог.
                  Ответить
                  • типа состояние "подпрограммы" сбрасывается в стек?
                    Ответить
              • а чего ты не за qnx? там чуть ли не на дискету влезала
                Ответить
                • > дискету
                  > килобайт
                  Ответить
                  • так там реалтаймовая ос с честными квантами времени , и процессы вытесняются же

                    QNX released a demo image that included the POSIX-compliant QNX 4 OS, a full graphical user interface, graphical text editor, TCP/IP networking, web browser and web server that all fit on a bootable 1.44 MB floppy disk.
                    Ответить
          • >всё будет на него переписано.

            После этих жутких ассемблерных выхлопов я с ужасом понимаю КАК индустрия умудрится сделать софт ещё медленее.

            В принципе тренд деградации софта на следующее десятилетие мне уже понятен.
            Ответить
            • возьми ситуацию в свои руки

              накажи анскильных лалок
              Ответить
          • показать все, что скрытоvanished
            Ответить
    • показать все, что скрытоvanished
      Ответить
      • > кабель говно

        Запросто, там частоты то конские на таком разрешении. А на самом компе то норм идёт?
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • Хер знает, может быть синхронизацию теряет из-за помех и ждёт до следующего vblank. Там же несколько категорий HDMI кабелей ещё, самый простой даже 1080@60 не вытягивает по частотам. Всё как с витухой.

            У меня 1080p@120 моник через display port подключен кстати.
            Ответить
            • кстааати
              надо бы провентилировать этот вопрос: если там есть DP и в ящике и компе, то надо бы их по нему запустить.

              нету DP ни там, ни там:(

              vblank это тот самый "обратный ход луча"?:) То есть он пол кадра нарисовал, а потом запутался, и стал ждать следующего кадра, а ящик в это время увидел, что сигнал потерялся, и не "флипнул" картинку на экран?
              Ответить
              • Х.з., возможно.

                Мне почему-то все советовали 120Гц моник подключать именно через display port, а от hdmi плевались.
                Ответить
                • ну он вроде более новый, хотя я хз пока в чем разниц
                  на самом деле TMDS можно даже по DVI гонять, но там наверное большие резолюшены и частоты не вызвать.

                  В любом случае -- выбора у меня нет: ни ящик, ни комп не умеют в DP.
                  Ответить
        • показать все, что скрытоvanished
          Ответить
          • > или тормозит или нет

            Или теряет данные или нет. Ретрансмитов то нету, там тупо RGB поток. И кодов коррекции нету, 8b/10b вроде только. Плохой кабель для него смертелен.
            Ответить
            • ну окей: кабель или умеет работать на частоте, заявленной стандартом, или не умеет.

              или типа может работать на частоте, но терять только N% данных, и если ты смотришь телепрограмму за пивом, то тебе похуй, а если ты видеорежиссер например, то тебе не похуй совсем
              так?

              хотя вот может быть еще что они все заявляют 120, но в реальности нкито на ней не работает, кроме таких вот дорогих
              Ответить
              • Ну в идеале - да, либо работает на заявленных частотах либо нет.

                Но на практике у тебя складываются проблемы передатчика, коннекторов, кабеля и приёмника. И чем больше дырка в глазковой диаграмме - тем больше шансов, что взлетит.

                Да и китайцы не особо то и тестят свои кабели.
                Ответить
                • Ты бы доверял кабелю за 1200 рублей, на котором написано 8K? Будет он работать на 1080 на 60?
                  Может, надо правда брать американский за 8000 минимум?
                  Ответить
                  • Ну вот у меня 2 метра за 1200р. 1080@60 на втором монике тащит. Давай попробую на основной.
                    Ответить
                    • спасибо, проверь, это интересно) Я в выхи тоже проверю.

                      А как телек выбирает частоту? Он неебических размеров там, на пол стены (это не у меня дома), он может захотеть например 120?
                      Хотя наверное поменять частоту можно попробовать в винде прямо.

                      Хотя причем тут размер? важно же разрешение наверное
                      Ответить
                      • Ну норм идёт, артефактов в игре не вижу, всё плавненько на 1080@120.

                        Телек вроде никак не выбирает, просто репортит что умеет. Выбираешь ты на стороне компа.
                        Ответить
                        • >плавненько
                          дзякую
                          >никак не выбирает
                          верно. у него это в EDID написино., а дальше карта
                          Ответить

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