Difference between revisions of "CSC231 Homework 10 2010"

From dftwiki3
Jump to: navigation, search
(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 1,000,000=
+
=Finding primes less than 2,000,000=
  
* The assembly program below tests all the integers between 2 and 1,000,000 and counts the number of primes found.   
+
* 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 = 1000000;
+
;  int N = 2000000;
 
;  int count = 0;
 
;  int count = 0;
 
;
 
;
Line 78: Line 78:
  
 
asm_main:
 
asm_main:
mov dword[N], 1000000 ; initialize 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.



Page under construction!
UnderConstruction.jpg

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;
}