Stories
Slash Boxes
Comments

Dev.SN ♥ developers

posted by LaminatorX on Saturday March 15 2014, @11:28PM   Printer-friendly
from the premature-optimization-is-the-root-of-all-evil dept.

Subsentient writes:

"I've been writing C for quite some time, but I never followed good conventions I'm afraid, and I never payed much attention to the optimization tricks of the higher C programmers. Sure, I use const when I can, I use the pointer methods for manual string copying, I even use register for all the good that does with modern compilers, but now, I'm trying to write a C-string handling library for personal use, but I need speed, and I really don't want to use inline ASM. So, I am wondering, what would other Soylenters do to write efficient, pure, standards-compliant C?"

 
This discussion has been archived. No new comments can be posted.
Display Options Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
  • (Score: 5, Interesting) by Debvgger on Sunday March 16 2014, @05:50AM

    by Debvgger (545) on Sunday March 16 2014, @05:50AM (#17136)
    From a gaming background, and having MAXIMUM speed in mind, ten things to remember:

    1) Never trust the compiler.
    2) Never trust the Standard Library.
    3) Never trust the compiler.
    4) Never trust any library you did not write.
    5) Never trust the compiler.
    6) Never trust any code you did not write.
    7) Never trust the compiler.
    8) Never trust your code.
    9) Never trust the compiler.
    A) ?

    Disassemble the code to gain understanding about how your compiler works and what is your code REALLY doing. How many parameters can you pass to a function before it resorts to using the stack? How does it recycle variable values? What is it doing with your array accesses? So many things to have in mind.

    Get used to reading assembler code. It is not THAT hard: There are too many myths about assembler, but in fact it is one of the easiest languages you can use because it's small size and few rules. Yes, it produces long and what -at first- resembles like somewhat cryptic code. But it is NOT: what you read is half people whining because they don't want to spend a few months improving their skills, half social pressure making them learn using some tools they later can't stop using. You will be amazed at how unbelievably bad are compilers in general, and also be amazed at how sometimes the compiler does an amazing trick you were not expecting. It is truly amazing to see how compilers struggle to implement basic SIMD instruction optimizations, how bad the floating point code is, etc. If you work with architectures like ARM the high level code is laughable due to short-sighted use of the fantastic ARM conditional code execution.

    Every compiler VERSION behaves differently. Compilers improve constantly. But since I started programming I have been hearing these good old "compilers produce better code than humans" and "computers today have so many mhz that asm is unnecessary" bullshit. The first time I was told the later we were using 486sx clocked at 25 mhz. Eat my balls, dude.

    The thing is, to produce SHARP code you need to understand what's happening in the lower levels. Don't be in a hurry. Good things need time, and need work. Don't be sucked into these modern ideas of writing a lot of code in as few time as possible. You are not a slave, you are an artist. You will find many slaves, angry with the life, throwing bullshit at you trying to deceit themselves.

    Having said that, the tenth rule:

    A) Do not trust ANYONE: Always check yourself how things work on YOUR code for YOUR purpose.

    Everyone writes different code for different purposes. My words in this post can be a pile of bullshit for many people. For me, it is the golden rule I try to follow daily, and it works beautifully for me, for the type of stuff I work on.

    Also, as someone already pointed, profile often. It is a very good way to understand where your code is slowing down. Start disassembling the functions your program spends the most time on! You are usually only going to need to optimize a few things to get an immense speed gain.

    Oh, and by the way, always try to start optimizing the algorithms, of course :-)

    Suggested reading: http://graphics.stanford.edu/~seander/bithacks.htm l [stanford.edu]
    Starting Score:    1  point
    Moderation   +3  
       Insightful=1, Interesting=2, Total=3
    Extra 'Interesting' Modifier   0  
    Karma-Bonus Modifier   +1  

    Total Score:   5  
  • (Score: 5, Funny) by Fry on Sunday March 16 2014, @06:41AM

    by Fry (642) on Sunday March 16 2014, @06:41AM (#17143)

    1) Never trust the compiler.
    2) Never trust the Standard Library.
    3) Never trust the compiler.
    4) Never trust any library you did not write.
    5) Never trust the compiler.
    6) Never trust any code you did not write.
    7) Never trust the compiler.
    8) Never trust your code.
    9) Never trust the compiler.
    A) ?

    A one-based list? The horror...

  • (Score: 4, Insightful) by FatPhil on Sunday March 16 2014, @07:15AM

    I got through about half of your post, and didn't see the word "measure" once. Anyone who doesn't start with saying "measure" on the first line of their comment simply doesn't know anything about optimising.

    If the compiler produces shitty object code from your C, you're a shitty C programmer.

    I one ran one of my number-crunching inner loops through (vendor-supplied) simulators for Alpha and Power processors a couple of years back (I've not done any number crunching since then). The same portable C source for both. And the pipeline analyses told me that every single pipeline was 100% saturated, except where instruction dispatch was unable to get new instructions to them, but the instruction dispatch unit was totally saturated every clock tick. Both compilers had produced absolutely perfect object code, and my C code was un-microoptimisable. And as 99.9% of the time was spent in that routine. My job was done. Thank goodness for the high quality of C compilers!
    --
    Making a public pledge to no longer contribute to slashdot
  • (Score: 3, Insightful) by maxwell demon on Sunday March 16 2014, @08:26AM

    by maxwell demon (1608) on Sunday March 16 2014, @08:26AM (#17160)

    OK, reading your post, I conclude the right way to write code it to start with your own operating system (because otherwise you didn't write the kernel code, and thus cannot trust it).

    Oh, and only run it on a RISC architecture, because you simply cannot trust microcode written by someone else ... so, sorry, no x86.

    BTW, am I at least allowed to trust VHDL code, or am I supposed to build my own computer chips as well?

    --
    The Tao of math: The numbers you can count are not the real numbers.
  • (Score: 4, Interesting) by lajos on Sunday March 16 2014, @09:04AM

    by lajos (528) on Sunday March 16 2014, @09:04AM (#17164)

    Oh come on, this is just pure nonsense.

    Don't trust the compiler? Don't trust stl?

    What ends up happening is people will waste time rewriting basic things like string classes, containers, and you get a code base where you constantly have to interface between multiple implementations of the same thing.

    You of course won't implement half of what the stl gives you, because you say you don't need it. But others will, and will reimplement another quarter of the stls.

    You'll have bugs, that are hard to find, but will tout that your code runs 2.1% faster. You of course still won't support utf-8 or wchar, because those are stupid. Which will make your library work on one single architecture on one single operating system.

    Then some 16 year old comes in, links mono to your game, writes stuff in c# and his code runs twice as fast as yours. Supports utf-8, wchar and a thousand utility functions you thought were stupid, hence producing better and more.

    Now there is of course place for asm. But there is also one for the compiler, and the stl. Let's not fall for the extremes.

    Measure your performance, and optimize where needed.

    And a string class? Unless you are doing it for learning, just grab a well tested library.

  • (Score: 5, Insightful) by Anonymous Coward on Sunday March 16 2014, @09:56AM

    by Anonymous Coward on Sunday March 16 2014, @09:56AM (#17175)

    I've dealt with plenty of "don't worry I'm a game developer, I'm the best kind of programmer there is" programmers, your post is almost cliche. It's almost entertaining to tear their illusions down on StackOverflow, because they are so full of themselves, both when asking and answering questions. It's easy to spot them, because they always start their posts with "I'm a game programmer".

    Here are some hard truths:

    1. You are not as awesome as you think you are. Don't suffer from Not-Invented-Here-Syndrome. People that write code for a living have to accomplish goals, not rewrite that blitting routine for the 20th time.
    2. Don't bother reading assembly, rewriting routines, etc, until you've measured it. That's the glaring omission in your list.
    3. Writing code is not an art. It's creative work, but requires a lot of well established techniques. If you want to be employable, you have to show that you can construct programs that make sense to other programmers (so you use names, concepts, structures, algorithms, etc that are familiar to other programmers), that are maintainable.
    • (Score: 2) by Debvgger on Sunday March 16 2014, @12:33PM

      by Debvgger (545) on Sunday March 16 2014, @12:33PM (#17204)
      Sir, I wonder why it would have been different if I said "I work on banking applications". Too bad for you if you have a problem with someone starting a post putting their next words into proper context, or about someone having a sort of (honest) job. I was talking about getting MAXIMUM (in CAPS) speed, from a gaming perspective. Sorry if what I do and how I have to do it is not what you do and how yo do it. The world is full of differences, learn to bare with it.

      About the points you make:

      1) I'm not bragging about anything, and probably would be getting more in another field, for example yours. I'm glad for you. I'm also glad so many people suffer the "not invented here syndrome" that brought to the development of all the libraries you use, because thanks to that we are not still eating bananas in a tree.

      2) My post says clearly to profile to know what functions are the time hoggers, investigate to write better algorithms and disassemble them to know how your compiler interprets your code, to be able to write them in the best way you can think. I'm surprised that my post was too long to read for someone who writes code in as few time as possible for a living and to accomplish goals, as you should surely have more time than me. Now tell me about wifes and kids. Yeah, I have these too, and still can afford to spend some extra time studying my own code to improve it.

      3) I understand painting walls and facades is not what you study at beaux-arts at the university. There are many types of people who use paint. All are necessary, and all are respectable. There are many types of people who use a compiler, too. There are many metrics you can use to measure code quality, but we were talking about maximum speed, and if you truly think anything I said is in detriment of good code quality I'm afraid you have a deep understanding problem, a programming problem, or both, but in any case you would not last too much at my job place. Not that you would want to get it, of course. Usually people painting facades get much more than these trying to change the world with a brush. I also compose music. Maybe not an art, also, because you can hit bongos with your balls :-)

      No need to be angry with the rest of the world, dude :-)
      • (Score: 0) by Anonymous Coward on Sunday March 16 2014, @12:53PM

        by Anonymous Coward on Sunday March 16 2014, @12:53PM (#17207)

        "The world is full of differences, learn to bare with it."

        Indeed, if we all bare with it then some major differences that split the world population in two will become obvious.

  • (Score: 1) by rochrist on Sunday March 16 2014, @01:11PM

    by rochrist (3737) on Sunday March 16 2014, @01:11PM (#17212)

    So....you're saying never trust the compiler?

  • (Score: 1) by fnj on Sunday March 16 2014, @02:07PM

    by fnj (1654) on Sunday March 16 2014, @02:07PM (#17224)

    Worst possible advice. Yes, SOME of it had SOME validity in the 1980s. It is all bunk now.
    1) For compilers on the order of gcc and clang, and probably even Visual C++, the compiler writers know more than you could possibly imagine about creating efficient machine code.
    2) For the 8088 you could do a lot with hand optimization. For CPUs of the last 20 years, you will only make the performance worse.
    3) Do not fixate on optimization. Straightforward C code on today's CPUs is orders of magnitude better in performance than you will ever need or notice for almost all tasks, and the benefits of trickery and cleverness, if any, will be miniscule and far exceeded by a few months of CPU tech progress.
    4) If the time comes that you ever do need to optimize, remember the 99%/1% rule. 99% of potential speed gains can be harvested by optimizing the critical 1% of the code.
    5) Write for human comprehension and maintenance. Do not waste time trying to "help" the compiler be "smarter", and do not show off by using obscure tricks no one else is going to understand.
    6) Staring at assembly level compiler output isn't going to do crap for code efficiency. The days when a table of individual instruction timing values told you anything of value, or was even possible to create, are long gone. Pipelining, out of order execution, speculative branch prediction, and the like are the order of the day.
    7) Leverage existing libraries. They have been through more debugging using more distributed brain power than anything you write is ever going to get.

    • (Score: 0) by Anonymous Coward on Sunday March 16 2014, @02:34PM

      by Anonymous Coward on Sunday March 16 2014, @02:34PM (#17230)

      For compilers on the order of gcc and clang, and probably even Visual C++, the compiler writers know more than you could possibly imagine about creating efficient machine code.

      Citation needed. Who are these superhuman compiler gods who have powers of logic comprehension beyond mere mortals like us?

    • (Score: 1) by smellotron on Sunday March 16 2014, @04:30PM

      by smellotron (3346) on Sunday March 16 2014, @04:30PM (#17260)

      For compilers on the order of gcc and clang, and probably even Visual C++, the compiler writers know more than you could possibly imagine about creating efficient machine code.

      When optimizing, a large part of the value in inspecting the compiler-generated object code is in identifying pessimizations that the compiler was forced to make to follow the language standard. It is very common in code that I write (not games, but still latency-sensitive) that some trivial reordering of operations in the C code will reduce or remove stack usage, or replace a nested function call with a tail call. Especially because compiler writers tend to be the sharpest optimizers in the room, there is value in double-checking their output to detect data-dependency/optimization bugs in your code.