Difference between revisions of "CSC231 Homework 10 2010"
(Created page with '--~~~~ ---- <tanbox> This assignment is due on the last day of class, Tuesday 12/14 evening, at midnight. </tanbox> <br /> __TOC__ <br /> <center> <font size="+2">Page under c…') |
(→Finding primes less than 1,000,000) |
||
Line 18: | Line 18: | ||
* Using compiler optimization techniques, modify the program below and make it run faster. | * Using compiler optimization techniques, modify the program below and make it run faster. | ||
− | =Finding primes less than | + | =Finding primes less than 2,000,000= |
− | * The assembly program below tests all the integers between 2 and | + | * The assembly program below tests all the integers between 2 and 2,000,000 (not included) and counts the number of primes found. |
<code><pre> | <code><pre> | ||
Line 45: | Line 45: | ||
; | ; | ||
;int main(){ | ;int main(){ | ||
− | ; int N = | + | ; int N = 2000000; |
; int count = 0; | ; int count = 0; | ||
; | ; | ||
Line 78: | Line 78: | ||
asm_main: | asm_main: | ||
− | mov dword[N], | + | mov dword[N], 2000000 ; initialize N |
mov dword[count], 0 ; initialize count | mov dword[count], 0 ; initialize count | ||
Line 161: | Line 161: | ||
ret 4 | ret 4 | ||
+ | |||
+ | </pre></code> | ||
+ | |||
+ | * When run on grendel at 7:00 p.m., here are the execution times observed: | ||
+ | |||
+ | <code><pre> | ||
+ | for i in 1 2 3 4 ; do time findPrime; echo ; done | ||
+ | |||
+ | 148933 | ||
+ | |||
+ | real 0m4.220s | ||
+ | user 0m4.207s | ||
+ | sys 0m0.001s | ||
+ | |||
+ | 148933 | ||
+ | |||
+ | real 0m4.236s | ||
+ | user 0m4.208s | ||
+ | sys 0m0.002s | ||
+ | |||
+ | 148933 | ||
+ | |||
+ | real 0m4.272s | ||
+ | user 0m4.246s | ||
+ | sys 0m0.003s | ||
+ | |||
+ | 148933 | ||
+ | |||
+ | real 0m4.267s | ||
+ | user 0m4.207s | ||
+ | sys 0m0.003s | ||
+ | </pre></code> | ||
+ | :So, the program takes about 4.24 seconds of user time to find all the primes less than 2,000,000. | ||
+ | |||
+ | * Your assignment is to modify the assembly language program using some of the ''compiler optimization'' techniques we covered in class, and lower its user execution time. | ||
+ | |||
+ | =Comparison= | ||
+ | |||
+ | * The C program used as documentation in the assembly program above is shown below: | ||
+ | |||
+ | <code><pre> | ||
+ | // findPrime.cpp | ||
+ | // D. Thiebaut | ||
+ | // computes the number of prime integers less than 2,000,000 | ||
+ | // and prints out this number | ||
+ | // | ||
+ | // To compile and run: | ||
+ | // g++ -o findPrime2 findPrime.cpp | ||
+ | // ./findPrime2 | ||
+ | // | ||
+ | // To compile and use as much optimization as the compiler can generate: | ||
+ | // g++ -O3 -o findPrim3 findPrime.cpp | ||
+ | // ./findPrime3 | ||
+ | // | ||
+ | |||
+ | #include<iostream> | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | //------------------------------------------------------ | ||
+ | // prototypes | ||
+ | bool isPrime( int n ); | ||
+ | |||
+ | //------------------------------------------------------ | ||
+ | int main(){ | ||
+ | int N = 2000000; | ||
+ | int count = 0; | ||
+ | |||
+ | //--- test all integers less than 2,000,000 --- | ||
+ | for ( int n = 2; n < N; n++ ) | ||
+ | if ( isPrime( n ) ) | ||
+ | //cout << n << endl; | ||
+ | count++; | ||
+ | |||
+ | cout << count << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | //------------------------------------------------------ | ||
+ | // isPrime( int n ) | ||
+ | // return true (1) if n is prime, 0 otherwise | ||
+ | //------------------------------------------------------ | ||
+ | bool isPrime( int n ) { | ||
+ | for ( int i=2; i*i <= n ; i++ ) | ||
+ | if ( n % i == 0 ) | ||
+ | return 0; | ||
+ | |||
+ | return 1; | ||
+ | } | ||
</pre></code> | </pre></code> |
Revision as of 19:26, 7 December 2010
--D. Thiebaut 23:57, 7 December 2010 (UTC)
This assignment is due on the last day of class, Tuesday 12/14 evening, at midnight.
Your assignmnent
- Using compiler optimization techniques, modify the program below and make it run faster.
Finding primes less than 2,000,000
- The assembly program below tests all the integers between 2 and 2,000,000 (not included) and counts the number of primes found.
; findPrime.asm
; D. Thiebaut
;
; this program counts the number of primes number less than 1,000,000.
;
; to assemble and run:
;
; nasm -f elf -F stabs asm_io.asm
; nasm -f elf -F stabs findPrime.asm
; gcc -c driver.c
; gcc asm_io.o findPrime.o driver.o -o findPrime
;
; C++ version of the program
; --------------------------
;#include<iostream>
;
;using namespace std;
;
;bool isPrime( int n );
;
;int main(){
; int N = 2000000;
; int count = 0;
;
; for ( int n = 2; n < N; n++ )
; if ( isPrime( n ) )
; //cout << n << endl;
; count++;
;
; cout << count << endl;
; return 0;
;}
;
;bool isPrime( int n ) {
; for ( int i=2; i*i <= n ; i++ )
; if ( n % i == 0 )
; return 0;
;
; return 1;
;}
;
%include "asm_io.inc"
section .data
N dd 0 ; typically set to 1,000,000
count dd 0 ; number of primes found
n dd 0 ; variable tested for prime property
i dd 0 ; index of for loop
section .text
global asm_main
asm_main:
mov dword[N], 2000000 ; initialize N
mov dword[count], 0 ; initialize count
; for ( int n = 2; n < N; n++ )
; if ( isPrime( n ) )
; //cout << n << endl;
; count++;
mov dword[n], 2
forn: mov eax, dword[n]
cmp eax, dword[N]
jge endForn
if: push ax ; make room for returned value
push dword[n]
call isPrime
pop ax ; get returned boolean
cmp ax, 1
jne endif
inc dword[ count ]
endif:
inc dword[ n ]
jmp forn
endForn:
mov eax, [count] ; print count
call print_int
call print_nl
ret
;-----------------------------------------------------------------
; isPrime function.
; gets n in stack. Returns true/false through the stack
;
;bool isPrime( int n ) {
; for ( int i=2; i*i <= n ; i++ )
; if ( n % i == 0 )
; return 0;
;
; return 1;
;}
;-----------------------------------------------------------------
isPrime:
push ebp
mov ebp, esp
sub esp, 4 ; make room in stack for i
%define ip_ret word[ebp+12]
%define ip_n dword[ebp+8]
%define ip_i dword[ebp-4]
mov ip_i, 2
.for: mov eax, ip_i ; compare n to i*i
mov ebx, ip_i
mul ebx
cmp eax, ip_n
ja .endFor
.if: mov edx, 0 ; divide n by i
mov eax, ip_n
mov ebx, ip_i
div ebx
cmp edx, 0 ; test modulo (remainder)
jne .end_if
.ret0:
mov ip_ret, 0 ; return 0
mov esp, ebp
pop ebp
ret 4
.end_if:
inc ip_i
jmp .for
.endFor:
mov ip_ret, 1 ; return 1
mov esp, ebp
pop ebp
ret 4
- When run on grendel at 7:00 p.m., here are the execution times observed:
for i in 1 2 3 4 ; do time findPrime; echo ; done
148933
real 0m4.220s
user 0m4.207s
sys 0m0.001s
148933
real 0m4.236s
user 0m4.208s
sys 0m0.002s
148933
real 0m4.272s
user 0m4.246s
sys 0m0.003s
148933
real 0m4.267s
user 0m4.207s
sys 0m0.003s
- So, the program takes about 4.24 seconds of user time to find all the primes less than 2,000,000.
- Your assignment is to modify the assembly language program using some of the compiler optimization techniques we covered in class, and lower its user execution time.
Comparison
- The C program used as documentation in the assembly program above is shown below:
// findPrime.cpp
// D. Thiebaut
// computes the number of prime integers less than 2,000,000
// and prints out this number
//
// To compile and run:
// g++ -o findPrime2 findPrime.cpp
// ./findPrime2
//
// To compile and use as much optimization as the compiler can generate:
// g++ -O3 -o findPrim3 findPrime.cpp
// ./findPrime3
//
#include<iostream>
using namespace std;
//------------------------------------------------------
// prototypes
bool isPrime( int n );
//------------------------------------------------------
int main(){
int N = 2000000;
int count = 0;
//--- test all integers less than 2,000,000 ---
for ( int n = 2; n < N; n++ )
if ( isPrime( n ) )
//cout << n << endl;
count++;
cout << count << endl;
return 0;
}
//------------------------------------------------------
// isPrime( int n )
// return true (1) if n is prime, 0 otherwise
//------------------------------------------------------
bool isPrime( int n ) {
for ( int i=2; i*i <= n ; i++ )
if ( n % i == 0 )
return 0;
return 1;
}