Dear readers, please note that this is the old website of maxEmbedded. The articles are now no longer supported, updated and maintained. Please visit the new website here and search for this post. Alternatively, you can remove .wordpress from the address bar to reach the new location.
We apologize for the inconvenience. We just want to give you a better viewing and learning experience! Thanks!
In this post, you get to know what optimization is, why do we need it, its causes, effects and an example.
Optimization. Many places we have come across it. Here in this short post, I will give the readers an idea of code optimization, what is it and why is it necessary. However I won’t go into the details as to how it is done and all.
What is it?!
Code optimization is a technique used by compilers in order to modify the program more efficient by utilizing fewer resources, or making it execute fastly, reduce compilation/building time, reduce size, drawing lesser power, effective memory usage, etc. But all this happens without changing the output or its side effects.
Talking in terms of embedded electronics, we use this built-in technique of the compiler in order to generate efficient hex/machine level files. Let’s take a small example.
Visit this post and do as directed. Create a new project, type in the same program, configure your project properly. Now during code optimization, choose the optimization level as -O0. Then build the project and view the hex file as directed in that post. You will see something like this:
:100000000C942A000C9447000C9447000C94470071 :100010000C9447000C9447000C9447000C94470044 :100020000C9447000C9447000C9447000C94470034 :100030000C9447000C9447000C9447000C94470024 :100040000C9447000C9447000C9447000C94470014 :100050000C94470011241FBECFE5D8E0DEBFCDBF12 :1000600010E0A0E6B0E0E6EEF4E002C005900D92EC :10007000A036B107D9F710E0A0E6B0E001C01D92AC :10008000A036B107E1F70E9449000C9471020C946C :1000900000000F931F93CF93DF93CDB7DEB76C971C :1000A0000FB6F894DEBF0FBECDBF84E390E021E031 :1000B000FC01208385E390E021E0FC01208380E0C7 :1000C00090E0AAEFB3E489839A83AB83BC83698110 :1000D0007A818B819C8120E030E04AE755E40E94E0 :1000E000E601DC01CB018D839E83AF83B88711E0ED :1000F0006D817E818F81988520E030E040E85FE36C :100100000E94650188230CF010E0112329F081E0A2 :1001100090E09A87898746C011E06D817E818F814A :10012000988520E03FEF4FE757E40E94E201181660 :100130000CF010E0112361F169817A818B819C813F :1001400020E030E040E251E40E94E601DC01CB0116 :10015000BC01CD010E946901DC01CB019A8789872E :1001600012C080E991E09C878B878B859C858C01F0 :10017000C8010197F1F78C011C870B8789859A8547 :1001800001979A87898789859A85009751F717C0C3 :100190006D817E818F8198850E946901DC01CB0190 :1001A0009A87898789859A859E878D878D859E8583 :1001B0008C01F8013197F1F78F011E870D8785E3D8 :1001C00090E0FC01108280E090E0AAEFB3E48F871A :1001D000988BA98BBA8B6F85788989899A8920E059 :1001E00030E04AE755E40E94E601DC01CB018B8B4D :1001F0009C8BAD8BBE8B11E06B897C898D899E8930 :1002000020E030E040E85FE30E94650188230CF0C5 :1002100010E0112329F081E090E0988F8F8B46C089 :1002200011E06B897C898D899E8920E03FEF4FE743 :1002300057E40E94E20118160CF010E0112361F15E :100240006F85788989899A8920E030E040E251E41D :100250000E94E601DC01CB01BC01CD010E946901D5 :10026000DC01CB01988F8F8B12C080E991E09A8FCF :10027000898F898D9A8D8C01C8010197F1F78C01C6 :100280001A8F098F8F89988D0197988F8F8B8F89FF :10029000988D009751F718C06B897C898D899E894C :1002A0000E946901DC01CB01988F8F8B8F89988D1B :1002B0009C8F8B8F8B8D9C8D8C01F8013197F1F782 :1002C0008F011C8F0B8FF6CEF5CE2FD008F481E076 :1002D000089557D088F09F5790F0B92F9927B751BC :1002E000A0F0D1F0660F771F881F991F1AF0BA95FA :1002F000C9F712C0B13081F05ED0B1E008955BC0A3 :10030000672F782F8827B85F39F0B93FCCF38695EF :1003100077956795B395D9F73EF49095809570954C :1003200061957F4F8F4F9F4F0895990F0008550F8C :10033000AA0BE0E8FEEF16161706E807F907C0F06B :1003400012161306E407F50798F0621B730B840B73 :10035000950B39F40A2661F0232B242B252B21F44D :1003600008950A2609F4A140A6958FEF811D811DED :10037000089557FD9058440F551F59F05F3F71F095 :100380004795880F97FB991F61F09F3F79F08795FC :100390000895121613061406551FF2CF4695F1DF85 :1003A00008C0161617061806991FF1CF8695710515 :1003B000610508940895E894BB2766277727CB0149 :1003C00097F90895B2DF08F48FEF08950BD078C045 :1003D00069D028F06ED018F0952309F05AC05FC09C :1003E0001124EACFC6DFA0F3959FD1F3950F50E01B :1003F000551F629FF001729FBB27F00DB11D639FD7 :10040000AA27F00DB11DAA1F649F6627B00DA11D7C :10041000661F829F2227B00DA11D621F739FB00D22 :10042000A11D621F839FA00D611D221F749F332792 :10043000A00D611D231F849F600D211D822F762F2B :100440006A2F11249F5750408AF0E1F088234AF028 :10045000EE0FFF1FBB1F661F771F881F9150504074 :10046000A9F79E3F510570F014C0A6CF5F3FECF393 :10047000983EDCF3869577956795B795F795E79560 :100480009F5FC1F7FE2B880F911D9695879597F971 :10049000089597F99F6780E870E060E008959FEF06 :1004A00080EC089500240A9416161706180609060B :1004B000089500240A9412161306140605060895DA :1004C000092E0394000C11F4882352F0BB0F40F462 :1004D000BF2B11F460FF04C06F5F7F4F8F4F9F4FA2 :0604E0000895F894FFCF1F :00000001FF
Haha, don’t worry, I won’t ask you to decipher it! Now change the optimization level to O2, build the project and then view the hex file again. What do you see?
:100000000C942A000C9447000C9447000C94470071 :100010000C9447000C9447000C9447000C94470044 :100020000C9447000C9447000C9447000C94470034 :100030000C9447000C9447000C9447000C94470024 :100040000C9447000C9447000C9447000C94470014 :100050000C94470011241FBECFE5D8E0DEBFCDBF12 :1000600010E0A0E6B0E0E4ECF0E002C005900D92F4 :10007000A036B107D9F710E0A0E6B0E001C01D92AC :10008000A036B107E1F70E9449000C9460000C947F :10009000000081E084BB85BB2FEF39E648E12150A9 :1000A00030404040E1F700C0000015BA2FEF39E6BC :1000B00048E1215030404040E1F700C00000EBCF64 :0400C000F894FFCFE2 :00000001FF
Hey, don’t be shocked! This is what optimization is! Question answered! 😀
Why is it necessary?
Well, I would like to put forth the above question as What if I don’t optimize my code?
Ideally speaking, microcontrollers and processors are supposed to be programmed in assembly language, which seems like Greek to most people. So we usually program in some higher level language like C, C++, python, JAVA, etc. and leave the rest of the headache to the compiler which compiles and builds our code. Now it all depends upon the compiler how it converts the code and builds it.
Now there lies the problem. The compiler is nothing but a software with some rules. So many a times, during compilation, the outcome is very inefficient. This is why modern compilers come with several options for code optimization. The outcome is usually a better and efficient file. The newer file may require fewer resources (like it utilizes lesser RAM), may require lesser program program memory, may reduce the execution time, etc. An example is shown above where after optimization, the size of the hex file is drastically reduced!
But how come same code results in more optimized code?
But how come the same high level code result in a more optimized low level code? Well, there may be many reasons, there is no particular answer to this. It might have compressed your code, or removed the comments, or removed the repeated portion of the code, or removed any variables that you may not have used, changed your code structure to result in an equivalent one with lesser clock cycles, tweaked the assembly a little, etc. As embedded developers, we need not go into these details and have faith in the compiler we use to generate the most optimum code. But as programmers, you should have some idea as to how you can tweak the assembly code and learn a bit about optimization.
I suggest you all to take some time and read the following tutorial at AVR Freaks. This would give you a clear understanding of Optimization and the importance of volatile in GCC.
Please comment below if you like to share some ideas. I will be glad to see them. For more updates, you can subscribe to this site, or grab the RSS Feeds! See you around! 🙂