Announcement

Collapse
No announcement yet.

Is foolish currently develop in machine code, hexadecimal and assembly?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Is foolish currently develop in machine code, hexadecimal and assembly?

    .........
    Last edited by assembler; 23 December 2015, 10:22 AM.

  • #2
    ................
    Last edited by assembler; 23 December 2015, 10:22 AM.

    Comment


    • #3
      For most of us, yes.

      C isn't completely machine-independent (big endian/little endian), but assembly is very machine-dependent. There are also a lot of instructions, and for best results, you have to know not only what they do, but how fast they do it, and a lot of them aren't available on different platforms, or even revisions of the same one. Yes, you could optimize something to be extremely fast for a particular machine, but most of us aren't writing exclusively for, say, a Haswell CPU. Code written with fast Haswell-only instructions would likely not work on my Phenom CPU. What's more, assembly requires many many many lines of code to do anything, which is why higher-level things like FORTRAN came into use. What's more, high-level code is much easier for humans to read, so much easier to maintain.

      On a game console, if you needed that extra bit of performance, well... those don't change architectures very often, and they're both built on AMD APUs.

      Comment


      • #4
        In addition to what A Laggy Grunt describes, consider that when C was invented, developer time was much cheaper relative to processor time than today.

        Today, if writing your program in a higher level language gets you something that works faster, that's the path to take. If performance is a concern, you can still take that path - then profile the resulting code, and start to replace the performance-critical parts with C code or assembly using a foreign function interface.

        Comment


        • #5
          Originally posted by A Laggy Grunt View Post
          For most of us, yes.

          C isn't completely machine-independent (big endian/little endian), but assembly is very machine-dependent. There are also a lot of instructions, and for best results, you have to know not only what they do, but how fast they do it, and a lot of them aren't available on different platforms, or even revisions of the same one. Yes, you could optimize something to be extremely fast for a particular machine, but most of us aren't writing exclusively for, say, a Haswell CPU. Code written with fast Haswell-only instructions would likely not work on my Phenom CPU. What's more, assembly requires many many many lines of code to do anything, which is why higher-level things like FORTRAN came into use. What's more, high-level code is much easier for humans to read, so much easier to maintain.
          assembly is a fairly simple language
          y sure there is a fair bit to learn about how cpu's work till you can program in it, but after that the rest of the details are easy

          x86 cpu's have not changed much since i686 with amd64 being the biggest change
          so what you write would work on any x86 or amd64 cpu

          assembly does not require lots and lots of code
          C was made to be "portable assembly" and one line of C equals about ~1.2 - 10 lines of assembly depending on what kind of line it is

          assembly, like almost any other programming language, is "easy" to maintain if the code is well commented


          an example of a for loop
          Code:
          for (int i = 0; i < 100; i++) {
              //code
          }
          mov ecx, 0
          some_label:
          //code
          inc ecx
          cmp ecx, 100
          jng some_label

          that a compiler usually changes to:
          (and its easier for a human)

          mov ecx, 100
          some_label:
          //code
          dec ecx
          jnz some_label


          adding two numbers together is just "add register/memory, memory/register/intermediate"
          with the limitation there being that you can not have bout values in memory (but you can do like "add [memory_address], intermediate_value")
          and details like that

          Comment


          • #6
            Originally posted by gens View Post
            assembly is a fairly simple language
            y sure there is a fair bit to learn about how cpu's work till you can program in it, but after that the rest of the details are easy

            x86 cpu's have not changed much since i686 with amd64 being the biggest change
            so what you write would work on any x86 or amd64 cpu

            assembly does not require lots and lots of code
            C was made to be "portable assembly" and one line of C equals about ~1.2 - 10 lines of assembly depending on what kind of line it is

            assembly, like almost any other programming language, is "easy" to maintain if the code is well commented


            an example of a for loop
            Code:
            for (int i = 0; i < 100; i++) {
                //code
            }
            mov ecx, 0
            some_label:
            //code
            inc ecx
            cmp ecx, 100
            jng some_label

            that a compiler usually changes to:
            (and its easier for a human)

            mov ecx, 100
            some_label:
            //code
            dec ecx
            jnz some_label


            adding two numbers together is just "add register/memory, memory/register/intermediate"
            with the limitation there being that you can not have bout values in memory (but you can do like "add [memory_address], intermediate_value")
            and details like that
            Well, assembly might be "simple, readable, portable to x86, easy to maintain, does not require lots of code" to you, it is still much less simple, much less readable, much less portable, much less expressive, and much less easier to maintain than C. That only leaves performance, and it's not even always the case (most likely premature optimisation unless you've profiled and tested both).

            The use cases for which the downsides of assembly are compensated by the benefits are very very limited (thigh loops in media codecs? hash functions for brute force stuff?). Not because assembly is bad, simply because other tools are better.

            Comment


            • #7
              Originally posted by erendorn View Post
              Well, assembly might be "simple, readable, portable to x86, easy to maintain, does not require lots of code" to you, it is still much less simple, much less readable, much less portable, much less expressive, and much less easier to maintain than C. That only leaves performance, and it's not even always the case (most likely premature optimisation unless you've profiled and tested both).

              The use cases for which the downsides of assembly are compensated by the benefits are very very limited (thigh loops in media codecs? hash functions for brute force stuff?). Not because assembly is bad, simply because other tools are better.
              with a properly documented coding standard it is not a lot more complicated then C

              again, C was made as portable assembly as the original authors made C just because they were tired of porting programs from one architecture to another
              as back then every new computer had a new architecture


              i do however disagree more about other tools being much better performance wise
              for example register allocation comes natural to humans, while compilers struggle with it
              gcc as one of the most performance orientated compilers changed its register allocation algorithm to an objectively worse one because it was simpler (last one was hard to maintain)
              talking about optimizing compilers and how they make decisions is a big topic
              in short id say a mediocre assembly programer can beat a modern optimizing compiler in most cases

              and ye, you hit the spot with media codecs and similar data processing loops
              to get the most out of a cpu everything has to be "vectorized" and more importantly data layout and access must be carefully considered
              (memory access is way slower then actual processing)

              for example the intels embree ray tracing kernel has a special format for storing vertices just because of that
              instead of storing them as you normally would (x,y,z,x,y,z...) it stores them like x,x,x,x,y,y,y,y,z,z,z,z to make it easy to process using SIMD
              (SSE register stores/processes 4 floats at a time)

              and a lot more can be written on the topic
              before people start citing things of the internet,
              i'l say that it is good to know how to program in assembly even though you never will use it
              and it's good to write a loop for performance even though the rest of the program is in C

              Comment


              • #8
                Actually, compilers do better at register allocation then humans. Take the iterator of a FOR loop; you'd think that keeping that in a register is good for performance, but most times, compilers will swap it out to free up a register. And 9/10 times, the compiler is right.

                Most languages have some form of the REGISTER keyword, which is a request to keep some variable in a register if at all possible. Try using it where you think it should be used, and compare performance.

                Comment


                • #9
                  Originally posted by gamerk2 View Post
                  Actually, compilers do better at register allocation then humans. Take the iterator of a FOR loop; you'd think that keeping that in a register is good for performance, but most times, compilers will swap it out to free up a register. And 9/10 times, the compiler is right.

                  Most languages have some form of the REGISTER keyword, which is a request to keep some variable in a register if at all possible. Try using it where you think it should be used, and compare performance.
                  ?
                  there is no way to make a loop without using a register
                  if you know assembly please do show me a way

                  well, there is a way
                  cmp instruction can compare a value in memory with an intermediate value
                  and dec instruction can also be used on a value in memory
                  but as i said you don't want to touch memory if you don't have to, as it is a lot slower

                  so if you have under 16 variables on amd64, you want to have them all in registers (8 for x86)

                  and no, compilers are worse at choosing what registers are for what
                  make a small c program and look at what the compiler produces
                  you can use this or just objdump (-M intel for intel syntax)


                  but i'm still interested in your 9/10 cases
                  please do present a couple
                  Last edited by gens; 29 October 2014, 03:09 PM.

                  Comment


                  • #10
                    Originally posted by gens View Post
                    ?
                    there is no way to make a loop without using a register
                    if you know assembly please do show me a way

                    well, there is a way
                    cmp instruction can compare a value in memory with an intermediate value
                    and dec instruction can also be used on a value in memory
                    but as i said you don't want to touch memory if you don't have to, as it is a lot slower

                    so if you have under 16 variables on amd64, you want to have them all in registers (8 for x86)

                    and no, compilers are worse at choosing what registers are for what
                    make a small c program and look at what the compiler produces
                    you can use this or just objdump (-M intel for intel syntax)


                    but i'm still interested in your 9/10 cases
                    please do present a couple
                    I am pretty sure x86 can do loops without using registers.
                    And x86 is pretty much the best example why compilers typically are better than (most) assembly programmers. The assembly you write gets transformed internally, modern cpu have more registers internally than you can access directly (OOO + register renaming) and timings can vastly change between cpus.

                    Noone doubts that you can write the most optimal code in asm, this is easily proved as you could just use the produced assembly from whatever language that claims to be faster. But thats not the point.

                    Unless you are a real asm pro and know the target cpu from ground up you will have a hard time competing with eg. good C/C++ code. The more complicated the CPU the harder it is to know it from ground up, I can accept if you claim to write nearly perfect Arm/Mips asm, I really doubt it if you claim this for x86.
                    Its much easier and more productive if you get to know C/C++ and learn to write good C/C++ code, by that I mean writing code that the compiler is allowed to fully optimize. A compiler has to rather strict and is expected to behave exactly as you typed it in every corner case. A good article on this subject is for example This one.

                    To sum up, instead of writing anything in asm from the start I`d go along this way:
                    • Write C/C++ Code
                    • Look at the assembly, try to fix your C/C++ code to produce better assembly
                    • If the compiler could reasonably do a better job, fix it or get it fixed
                    • Write inline asm if the part is really crucial


                    For reference, I regulary write arm asm, but mostly because there are parts in theOS where you dont have a full C/C++ context (stack, reserved registers, irq handlers). The pieces with inline asm are kept to a minimum and are typically wrapped in inline-functions

                    Comment

                    Working...
                    X