CS 3330: Lecture 5: Assembly Performance

This page does not represent the most current semester of this course; it is present merely as an archive.

About Bits and Masking

We'll start today with a discussion of bitmasks and some related fiddles. In particular, we'll discuss

Code Behavior
!!x x != 0 ? 1 : 0
~(!!x)+1 x != 0 ? 0xffffffff : 0
a&B | ((~a)&C) a ? B : C, assuming that a was either 0 or 0xffffffff
x<<32 does nothing (shifts must be between 0 and 31)
~((~0)<<x) 0s followed by exactly x 1s.

Stacks, pushl and popl, arguments and returns

As described in the textbook. We'll take questions, if there are none we'll move on.

Timing with rdtsc

x86 has a special assembly operations rdtsc that reads the time stamp counter, a 64-bit counter that is incremented every single clock cycle. It lets us measure the exact time taken by each operation.

We can use GCC's inline assembly options to access the time stamp counter:

/*------------------- BEGIN CYCLE COUNTER CODE -----------------------*/
#if defined(__i386__)
static __inline__ unsigned long long rdtsc(void) {
    unsigned long long x;
    __asm__ volatile ("rdtsc": "=A" (x));
    return x;
}
#elif defined(__x86_64__)
static __inline__ unsigned long long rdtsc(void) {
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc": "=a"(lo), "=d"(hi));
    return (((unsigned long long)hi)<<32) | ((unsigned long long)lo);
}
#else
#error "No cycle counter available"
#endif
/*-------------------- END CYCLE COUNTER CODE ------------------------*/

You can get this code from this lectures' template .c file. See also this lectures' template .s file.

Hand-crated Assembly

We'll work today on exploring the impact of the ISA by hand-crafting assembly code and comparing it to GCC's generated assembly.

To add assembly for a method we write extern in front of the method header in the c code, as e.g.

extern unsigned cruton(int x, unsigned y);

and we add a .s file that contains the code

.globl cruton
cruton:
    // header code
    pushl   %ebp
    movl    %esp, %ebp
    
    // load the arguments
    movl    8(%ebp), %eax   /* eax = first parameter */
    movl    12(%ebp), %ecx  /* ecx = second parameter */
    
    // main code goes here
    
    // footer code
    popl    %ebp
    ret

Some guidelines for GCC assembly files:

Copyright © 2015 by Luther Tychonievich. All rights reserved.
Last updated 2014-09-11 13:51 -0400