Χ
With visiting this site I accept that it uses cookies for website analytics.
Learn more
Fachbereich Informatik
Login (Group Members)
Embedded Systems Group (ES)
Toggle navigation
RPTU
FB
Home
People
Teaching
Research
Publications
Conferences
Tools
Tools
Overview
Averest
Teaching Tools
Jobs
Fachbereich INF
ES
Startseite
Examples for Mini C Compiler
Insertion Sort (First Version)
// ----------------------------------------------------------------------------- // This file implements the well-known insertion sort procedure. The main idea // is to sort prefixes x[0..i-1] of the array x[0..N-1] and then store x[i] in // a separate variable y so that all entries x[j+1..i-1] can be moved one place // to the right and y can be stored at x[j+1]. // ----------------------------------------------------------------------------- thread InsertionMaxSort { [10]nat x; nat i,j,yind,yval; // first create a test array in reverse order for(i=0..9) { x[i] = 10-i; } // now apply insertion sort for(i=0..9) { // compute maximum of x[0..N-1-i] j = 0; yval = x[j]; for(j=1..9-i) if(x[j]>yval) { yval = x[j]; yind = j; } // now yval is the maximum of x[0..N-1-i] and is swapped with x[N-1-i] j = 9-i; x[yind] = x[j]; x[j] = yval; } }
Insertion Sort (Second Version)
// ----------------------------------------------------------------------------- // This file implements the well-known insertion sort procedure. The main idea // is to sort prefixes x[0..i-1] of the array x[0..N-1] and then store x[i] in // a separate variable y so that all entries x[j+1..i-1] can be moved one place // to the right and y can be stored at x[j+1]. // Note in many textbooks the while loop has condition (j>=0 & x[j]>y) and // no other code than x[j+1]=y is put after the loop. However, if conjunction // is commutative (as in MiniC and Quartz unlike in C), then in case of j==0, // the evaluation of this condition will not stop after j>=0 is seen false, // and instead also x[j]>y is evaluated which leads to a runtime error. // ----------------------------------------------------------------------------- thread InsertionSort { [10]nat x; nat i,j,y; // first create a test array in reverse order for(i=0..9) { x[i] = 10-i; } // now apply insertion sort for(i=1..9) { y = x[i]; // for element x[i], find its place in j = i-1; // already sorted list x[0..i-1] while(j>0 & x[j]>y) { x[j+1] = x[j]; j = j-1; } // now j==0 or x[j]<=y if(x[j]>y) { // note that this implies j==0 x[j+1] = x[j]; x[j] = y; } else { // here we have x[j]<=y, so that y must be placed at j+1 x[j+1] = y; } } }
Matrix Multiplication
// ----------------------------------------------------------------------------- // The version below uses order k-j-i which is very bad, since the inner loop // will then access elements from a,b and c in different rows so that cache // hits are unlikely for all of these accesses. // ----------------------------------------------------------------------------- function MatrixMultV0 ([][]nat a,[][]nat b,[][]nat c,nat d1,d2,d3) : [][]nat { nat i,j,k; for(k=0..d3-1) for(j=0..d2-1) for(i=0..d1-1) c[i][j] = c[i][j] + a[i][k] * b[k][j]; return c; } // ----------------------------------------------------------------------------- // This version uses loop ordering i-j-k which is usually the definition found // in textbooks. This version is better than the previous one, since the // accesses to a and c are done in the inner loop in the same rows, but the // inner loop accesses in each iteration another row of b. // ----------------------------------------------------------------------------- function MatrixMultV1 ([][]nat a,[][]nat b,[][]nat c,nat d1,d2,d3) : [][]nat { nat i,j,k; for(i=0..d1-1) for(j=0..d2-1) for(k=0..d3-1) c[i][j] = c[i][j] + a[i][k] * b[k][j]; return c; } // ----------------------------------------------------------------------------- // The version below is much more cache-friendly than the previous versions, // since now the innermost loop accesses all array accesses in the same rows // which increases the chances to have cache hits. // ----------------------------------------------------------------------------- function MatrixMultV2 ([][]nat a,[][]nat b,[][]nat c,nat d1,d2,d3) : [][]nat { nat i,j,k; for(i=0..d1-1) for(k=0..d3-1) for(j=0..d2-1) c[i][j] = c[i][j] + a[i][k] * b[k][j]; return c; } // ----------------------------------------------------------------------------- // We can optimize the above version in that we factor out the array access to // matrix a which is always the same in the innermost loop. This way the number // of load instructions is reduced. // ----------------------------------------------------------------------------- function MatrixMultV3 ([][]nat a,[][]nat b,[][]nat c,nat d1,d2,d3) : [][]nat { nat i,j,k,x; for(i=0..d1-1) for(k=0..d3-1) { x = a[i][k]; for(j=0..d2-1) c[i][j] = c[i][j] + x * b[k][j]; } return c; } // ----------------------------------------------------------------------------- // The main thread generates some test examples, and then calls one of versions. // ----------------------------------------------------------------------------- thread MatrixMult { [4][5]nat a; [5][6]nat b; [4][6]nat c; nat i,j; // first create some test matrices a and b for(i=0..3) for(j=0..4) a[i][j] = i+j; for(i=0..4) for(j=0..5) b[i][j] = (i+1)*(j+1); for(i=0..3) for(j=0..5) c[i][j] = 0; // now call one of the above functions c = MatrixMultV3(a,b,c,4,5,6); }
Fibonacci Numbers
// ----------------------------------------------------------------------------- // This function computes the n-th Fibonacci number in linear time. // ----------------------------------------------------------------------------- function fibonacci(nat n) : nat { nat i,f1,f2,fn; if(n == 1 | n ==2) { fn = 1; } else { f1 = 1; f2 = 1; i = 2; while(i
Computing Square Roots (Heron's Iteration)
// ----------------------------------------------------------------------------- // The function below computes the integer approximation to the square root // of a given natural number a. It is known as Heron's algorithm, but is also // derived by the Newton-Raphson iteration of f(x) = x^2-a to compute roots. // ----------------------------------------------------------------------------- function heron(nat a) : nat { nat xold,xnew; xnew = a; do { xold = xnew; xnew = (xold + a/xold)/2; } while(xnew < xold) return xold; } thread Heron { nat z; z = heron(121); // compute the square root of 121 }
Computing Greatest Common Divisors (Euclid's Algorithm)
// ----------------------------------------------------------------------------- // The function below computes the greatest common divisor using Euclid's // algorithm. // ----------------------------------------------------------------------------- function euclid(nat a,b) : nat { nat t; while(b!=0) { t = b; b = a % b; a = t; } return a; } thread t2 { nat x,y,z; z = euclid(x,y); }
Computing Greatest Common Divisors (Extended Euclid's Algorithm)
// ----------------------------------------------------------------------------- // The function below computes the greatest common divisor using the extended // Euclidean algorithm. In addition to the greatest common divisor g of two // numbers a,b it also computes numbers s,t such that g = s*a + t*b holds. // ----------------------------------------------------------------------------- function extendedEuclid(nat a,b) : nat { nat q,r,s,t,old_r,old_s,old_t,y; r = b; s = 0; t = 1; old_r = a; old_s = 1; old_t = 0; while(r!=0) { q = old_r / r; y = r; r = old_r - q * r; old_r = y; y = s; s = old_s - q * s; old_s = y; y = t; t = old_t - q * t; old_t = y; } return old_r; } thread t2 { nat x,y,z; z = extendedEuclid(x,y); }
Radix-B and B-Complement Addition
// ----------------------------------------------------------------------------- // NatAdd is a ripple carry adder for radix-B numbers // ----------------------------------------------------------------------------- function NatAddSameLen([]nat x1,x2,[]nat sum,nat len) : []nat { nat c,g,p,s,i; c = 0; // initial carry digit for(i=0..len-1) { // ripple from least to highest digit g,s = x1[i] + x2[i]; // g:generate carry; s:preliminary sum p,sum[i] = s + c; // p:propagate carry; add previous carry c = (nat) ((bool) g | (bool) p); // define next carry digit 0 or 1 } sum[len] = c; // most significant digit is final carry return sum; } function NatAdd([]nat x1,x2,[]nat sum,nat len1,len2) : []nat { nat c,g,p,s,i,lmin; // determine set of common digits if(len1
Radix-B Multiplication
// ----------------------------------------------------------------------------- // NatMul is a radix-B Multipication // ----------------------------------------------------------------------------- function NatMul([]nat x1,x2,[]nat pr,nat len1,len2) : []nat { nat c,g,p,s,i,j; for(j=0..len2-1) { // compute pr[j+len1..j] = pr[j+len1-1..j] + x1[len1-1..0] * x2[j] c = 0; for(i=0..len1-1) { g,s = pr[i+j] + x1[i] * x2[j] + c; p,pr[i+j] = s + c; c = (nat) ((bool) g | (bool) p); } pr[len1+j] = c; } return pr; } thread NMul { [4]nat x; [8]nat y; [12]nat pr; pr = NatMul(x,y,pr,4,8); }
Zum Seitenanfang