Write efficient C program and C code optimization

Source: Internet
Author: User

From: codingwu-Blog Park

Author: Archimedes

Source: http://www.cnblogs.com/archimedes/

This article is translated from: http://www.codeproject.com/Articles/6154/Writing-Efficient-C-and-C-Code-Optimization


It refers to the article: http://www.cppblog.com/xlander/archive/2006/07/21/10289.html


But the code format in the article is not typeset, inconvenient to view, and there are some translation errors and other errors, this article in addition to reference to the original text and translation, but also added some of their own understanding and code, although it is a 2006-year article, but some of these skills are quite worth learning, and special reorganization to share with you.


While there are many effective guidelines for optimizing C code, the speed with which you get to know the compiler and the work you're working with is still not going to take place, and speeding up the program also increases the amount of code. These added code can also affect the complexity and readability of a program, this is not acceptable, for example, if you are programming on a small device, such as a mobile device, a PDA ..., these have strict memory limits, so the motto in optimization is: Write code in memory and speed should be optimized.


Integer number/integers


When we know that the number of uses can not be negative, you should use the unsigned int instead of int, some processors handle integer arithmetic when the unsigned int faster than int, so, in a compact loop inside the definition of an integer variable, it is best to write code:

Register unsigned int variable_name;

However, we cannot guarantee that the compiler will notice the Register keyword, and it is possible that for some processor, there is no unsigned. These two keywords are not available for use in all compilers. Remember, the integer operation is much faster than the floating-point number, because the processor can directly perform integer operations, floating-point operations need to rely on the external floating-point number processor or floating-point math library. We need to be more precise when dealing with decimals (for example, when we're doing a simple statistical program), limit the results to 100, and turn it into floating-point numbers as late as possible.


Division and Remainder/division and remainder


In a standard processor, depending on the numerator and denominator, a 32-bit division requires 20-140 clock cycles to perform, equal to a fixed time plus the time each bit is removed.

Time (numerator/denominator) = C0 + c1* log2 (numerator/denominator)

= C0 + C1 * (log2 (numerator)-log2 (denominator)).

Now the ARM processor needs to consume 20+4.3n clock cycles, which is a very time-consuming operation to avoid as much as possible. In some cases, a division expression can be overridden by a multiplication expression. For example, (A/b) >c can be written as a> (C*B), provided that we already know that B is non-negative and that b*c does not exceed the range of integer numbers. If we can determine that one of the operands is unsigned, then it would be better to use unsigned division because it is much faster than signed division.


Merging Division operations and Division operations/combining and remainder


In some cases, both the division and the remainder operations are needed, in which case the compiler merges the division and the rest operations because the division operation always returns both the quotient and the residue. If two operations are to be used, we can write them together.

int func_div_and_mod (int a, int b) {return 
     (A/b) + (a%);
}

Divisor is the division of the power of 2 and the remainder/division and remainder by powers of two


If the divisor in the division is a power of 2, we can further optimize the division operation, and the compiler uses the shift operation for this division operation. So, we want to adjust the power of 2 (say 64 instead of 66) as much as possible. If it is unsigned, it is much faster than a signed division.

typedef unsigned int uint;

UINT DIV32U (uint a) {

return A/32;

}

int div32s (int a) {

return A/32;

}

Both divisions avoid calling the division function, and in addition, unsigned division uses fewer instructions than a signed division. A signed division takes more time, because the division is the end result tends to zero, while the shift tends to negative infinity.


Substitution of modulo operation/an alternative for modulo arithmetic


We typically use the remainder operation for modulo, but sometimes it is possible to rewrite using an if statement. Consider the following two examples:

UINT MODULO_FUNC1 (UINT count)

{

Return (++count% 60);

}

UINT MODULO_FUNC2 (UINT count)

{

if (++count >= 60)

Count = 0;

return (count);

}

The second example is preferable to the first, because the code generated by it is faster, note: This is only when the count range is between 0–59.


But we can use the following code (the author added) to implement the equivalent function:


UINT MODULO_FUNC3 (UINT count)

{

if (++count >= 60)

Count%= 60;

return (count);

}

Use array index/using array indices


Suppose you want to set another variable to a specific character based on the value of a variable, and you might do this:

Switch (queue) {

Case 0:letter = ' W ';

Break

Case 1:letter = ' S ';

Break

Case 2:letter = ' U ';

Break

}

or so:

if (queue = 0)

letter = ' W ';

else if (queue = 1)

letter = ' S ';

Else

letter = ' U ';

A simple and quick way is simply to make the value of a variable a string index, for example:

static char *classes = "WSU";

letter = Classes[queue];

Globals/Global Variables


Global variables are not assigned to registers, and modifying global variables is done indirectly through pointers or by calling functions. So the compiler does not store global variables in registers, which can create additional, unnecessary burdens and storage space. So in the more critical loops, we don't use global variables.


If a function uses global variables frequently, we can use local variables as copies of global variables so that registers can be used. The condition is that any child functions called by this function do not use these global variables.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.