Week 4 notes

Comp 264-002, Spring 2019,MWF, 11:30-12:20, Cuneo 218

Readings (from BOH3)

Chapter 1 (though we haven't covered much of section 9 yet, on concurrency)

Section 2.1 (you can skip 2.1.7 for now, on bitwise operations, and 2.1.9 on shift operations)
Section 2.2 (don't sweat the B2Uw notation for now, though all it's doing is formally defining the conversion from strings of bits to integers)
Section 2.3 on integer arithmetic (we'll save floating point, in 2.4, for later)


How to start a program on boole.

C: see c.html

rows_and_columns.c: an illustration of the effect of caches. Row order and column order visit exactly the same array components, but in different orders.

branchpredict.c: an illustration of the effect of branch prediction. The two array passes -- before and after sorting -- do exactly the same work, just in different orders. Also, what's with that 'µ'? Is it a byte?

Monday:

tracking down struct timeval

rows_and_columns.java

gcc -O3 rows_and_columns.c -o rowcol3

How does changing the size affect things?

    rowcolarg.c

bit extraction: &, |, <<, >>

x & 0xFF

BOH3 p 86:
Security vulnerability in getpeername
In 2002, programmers involved in the FreeBSD open source operating systems project realized that their implementation of the getpeername library function had a security vulnerability. A simplified version of their code went something like this:

/*
* Illustration of code vulnerability similar to that found in
* FreeBSD’s implementation of getpeername()
*/

/* Declaration of library function memcpy */
void *memcpy(void *dest, void *src, size_t n);        // size_t is unsigned!

/* Kernel memory region holding user-accessible data */
#define KSIZE 1024
char kbuf[KSIZE];


/* Copy at most maxlen bytes from kernel region to user buffer */
int copy_from_kernel(void *user_dest, int maxlen) {
    /* Byte count len is minimum of buffer size and maxlen */
    int len = KSIZE < maxlen ? KSIZE : maxlen;    // sets len to min(KSIZE, maxlen)
    // if (KSIZE < maxlen) len = KSIZE; else len = maxlen;
    memcpy(user_dest, kbuf, len);
    return len;
}


BOH3 p 100:

In 2002, it was discovered that code supplied by Sun Microsystems to implement the XDR library, a widely used facility for sharing data structures between programs, had a security vulnerability arising from the fact that multiplication can overflow without any notice being given to the program. Code similar to that containing the vulnerability is shown below:

/*
 * Illustration of code vulnerability similar to that found in Sun’s XDR library.
 */
void* copy_elements(void *ele_src[], int ele_cnt, size_t ele_size) {
    /*
    * Allocate buffer for ele_cnt objects, each of ele_size bytes
    * and copy from locations designated by ele_src
    */
    void *result = malloc(ele_cnt * ele_size);
    if (result == NULL)      /* malloc failed */
        return NULL;
    void *next = result;
    int i;
    for (i = 0; i < ele_cnt; i++) {    /* Copy object i to destination */
        memcpy(next, ele_src[i], ele_size);
        /* Move pointer to next memory region */
        next += ele_size;
    }
    return result;
}

The user passes in ele_size, representing the amount of data to be copied.

What if ele_size = 4096 = 212, and ele_cnt = 1,048,577 = 220 + 1. Then, with 32-bit arithmetic, ele_cnt * ele_size is 4096 (why?).

That means that the malloc() call didn't allocate nearly enough memory, and so the memcpy() call copies waay too much data into next, causing memory corruption.


Wednesday:

For floating point, this is a useful reference: fabiensanglard.net/floating_point_visually_explained/index.php

Friday: just got to floating_point fractional part

Fractional part is 23 bits and can represent any value n/223, 0<=n<223. If we add a 1 to the left of the binary-point, we get a number between 1 and 2.

exponent: represents an unsigned value 0 ≤ expfield ≤ 255. The actual exponent is e = expfield - 127, if expfield != 0 and expfield != 255, so the range for e is -126 ≤ e ≤ 127. For e in this range, the fractional part is assumed to have a 1. in front of it. This is called the normalized case.

For expfield == 0, the number is denormalized. We still assume e=-126, but there is not an assumed 1. in front of the fractional part. That is, we go from:

    0    0000 0001   0 ... 000    // frac is 1.00...0

to

    0    0000 0000    1 ... 111        // frac is 0.111  ... 11

and on downward until

    0    0000 0000     0...00001

Representation of 0.0
    what is -0.0??

What is the smallest 32-bit float > 1.0?

What is the largest 32-bit float?

What is the smallest 32-bit float > 0.0?

Infinity and NaN

If expfield = 1111 1111, then if frac == 0... 000 the number represents +∞ or -∞, depending on the sign bit. If frac is any nonzero value, then the float represented is NaN: not a number.

Failure of associativity

Practice problem 2.54:

Which are true:

A. x == (int) (double)x

B. x == (int) (float) x

C. d == (double)(float) d

D f == (float)(double) f

E f == -(-f)

BOH3 example: 1 bit sign, 4 bit expfield, 3 bit fraction (p 116, fig 2.35)


Monotonicity: if u≤v, then x+u ≤ x+v. This is not true for integer arithmetic; one side may overflow.

Floating-point hardware

mysqrt(x) and accuracy to the last binary digit

mysqrt(1e6) and higher

What is the first int n for which (float) n == (float) (n+1)

float and ==: some people argue you should never use == with float.