www.pnITis.cm
|
LINuX For you
|
February 2008
c m yk
13
Insight
examples, x86 architecture will beused. A word o caution beore weproceed: the techniques and issuescovered are not or general-purposeprogramming.
Basic types
The machine, in general,understands only three types o values: address, integer and foating-point values. For representationand manipulation, here is thecorrespondence between the typesthat the machine can understandand what C supports. Addressescorrespond to the pointer construct;integers—both signed andunsigned—correspond to short, int,long, long long, char (yes, a char isrepresented as an int internally!) etc;foating-point types correspond tofoat, double, long double, etc.The most ecient data-typethat a processor handles is a ‘word’,which corresponds to ‘int’ typein C. For foating-point types, allcomputation is typically done ina larger foating-point type. Forexample, in x86 machines, allfoating-point computation is donein ‘extended precision’, which is 80bits in size and usually correspondsto ‘long double’ in C; i foating pointexpressions are used in the code,they are internally converted toextended precision by the processorand the results are converted backto foat (which occupies 32 bits).The processor does foating-pointcomputations in a separate ‘co-processor’ unit. Address computation (suchas array index access) is doneusing pointers in C. They directlycorrespond to memory accessoperations in the underlying machine(such as index addressing, in thiscase).The ‘int’ type is the most ecientor computations. Unsigned typesand operations on that are asecient as signed types. Floatingpoint types and operations are slowcompared to integral types. Forexample, in an imaginary processor,i integer division takes our cycles,foating point division operationmight take 50 to 100 cycles. Memoryaccess operations are very slow—i the desired memory location is not incache, then it might take hundreds o cycles to etch the data rom the mainmemory.
Operators
C supports a rich set o operators.There are ew operators that aredirectly supported by the processorand there are a ew that are simulatedin the sotware.For integral types, bit-manipulation operators are astercompared to other operators likearithmetic, logical or relationaloperators. One o the ways to writeecient code is to write code usingbitwise operations instead o otherslower operations. Here is a well-known example: Using ‘<<’ is moreoperator ecient than dividing aninteger value by 2. We’ll look at adierent example or illustrationhere. A typical code segment ortoggling a character’s case is to userelational operators, as in:
// precondition: the char ch providedis in range [‘a’-‘z’] or [‘A’-‘Z’]char toggle_ascii_char_case(char ch) {if( (ch >= ‘a’) && (ch <= ‘z’)) // lower casech = ch - 0x20;else if( (ch >= ‘A’) && (ch <=‘Z’) ) // upper casech = ch + 0x20;return ch;}
The code works on the ollowingassumption: the given char ch iswithin the range [a-z] or [A-Z]. I the char is [A-Z], it returns thecorresponding char in [a-z] and vice versa, that is, it toggles the case o the character. The value 0x20 isadded or subtracted based on the actthat the alphabetic characters areseparated by the hex value 0x20 inthe ASCII table.But this unction is slow. I this is a library unction used ortoggling the case o charactersin a string, then it is not a goodimplementation.The code can be improvedas ollows: since the comparisonoperators are not required, theunction precondition says thatch passed to the unction is in thegiven range [‘a’-‘z’] or [‘A’-‘Z’]. Basedon C tradition, we need not checkto ensure that the given char isin act in this range. Also, sincewe are perorming either the ‘-’ or‘+’ arithmetic operation, we canreplace it with bit-wise operationsor toggling the bit using the ex-or operator. With this the codebecomes ecient and simple:
// precondition: the char ch providedis in range [‘a’-‘z’] or [‘A’-‘Z’]char toggle_ascii_char_case(char ch){return (ch ^= 0x20);}
This example is just orillustration purposes. Using bit-wiseoperators obscures the code, but itusually signicantly improves theeciency o the code.
Control flow
C has various conditional andlooping constructs. A C compilertransorms such code constructsto branching (also known as‘jump’) instructions. So, goto is themost straightorward constructor programming. It is possible totake any C program and create anequivalent program by removing allconditions and loops with just gotostatements. Though it is ultimatelybranching instructions, there aresubtle dierences in constructswhen it comes to eciency.Which one is more ecient—nested i conditions or switchstatements? In general, a switchis more ecient than nested i statements. I both are implementedusing branching, why is switch moreecient than nested i conditions?Recall that, in a switch statement,all cases are constants. So, a
Leave a Comment