Created
July 10, 2012 17:17
-
-
Save grodtron/3084835 to your computer and use it in GitHub Desktop.
Little assignment for a programming class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Debug/* | |
*.vcxproj* | |
*.o | |
*.swp | |
test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "factorial.h" | |
unsigned long factorial::iterative(int n){ | |
unsigned long value = 1; | |
for(int i = 2; i <= n; ++i){ | |
value *= i; | |
} | |
return value; | |
} | |
unsigned long factorial::recursive(int n){ | |
if (!n) return 1; | |
return n * factorial::recursive(n - 1); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef factorial_h | |
#define factorial_h | |
namespace factorial{ | |
unsigned long iterative(int n); | |
unsigned long recursive(int n); | |
/* | |
The constants below are used with the timer to calculate approximate costs | |
of basic operations. The number of basic operations is going to be based on | |
lines of assembly code generated by g++. | |
The entire assembly code generated is given below. | |
Calculation of the cost of basic operations using this method depends on the | |
terrible assumption that all instructions take the same amount of time to | |
execute, but it should still give a good general idea. | |
*/ | |
const int numberOfIterativeOperations = 10; | |
/* | |
Stripping out all of the assembler directives, we get: | |
.LFB0: | |
pushl %ebp | |
movl %esp, %ebp | |
subl $16, %esp | |
movl $1, -8(%ebp) | |
movl $2, -4(%ebp) | |
jmp .L2 | |
== for loop body starts here == | |
.L3: | |
movl -4(%ebp), %eax | |
movl -8(%ebp), %edx | |
imull %edx, %eax | |
movl %eax, -8(%ebp) | |
addl $1, -4(%ebp) | |
.L2: | |
movl -4(%ebp), %eax | |
cmpl 8(%ebp), %eax | |
setle %al | |
testb %al, %al | |
jne .L3 | |
== for loop body ends here == | |
movl -8(%ebp), %eax | |
leave | |
ret | |
*/ | |
const int numberOfRecursiveOperations = 11; | |
/* | |
Generated assembly minus directives: | |
_ZN9factorial9recursiveEi: | |
== Stuff that is repeated starts here... == | |
.LFB1: | |
pushl %ebp | |
movl %esp, %ebp | |
subl $24, %esp | |
cmpl $0, 8(%ebp) | |
jne .L6 | |
== ...Until here == | |
movl $1, %eax | |
jmp .L7 | |
== Then from here.. == | |
.L6: | |
movl 8(%ebp), %eax | |
subl $1, %eax | |
movl %eax, (%esp) | |
call _ZN9factorial9recursiveEi | |
movl 8(%ebp), %edx | |
imull %edx, %eax | |
== ...'til here == | |
.L7: | |
leave | |
ret | |
*/ | |
/////////////////////////////////////////////// | |
// // | |
// Complete Generated GAS Code // | |
// // | |
/////////////////////////////////////////////// | |
/* | |
.file "factorial.cpp" | |
.text | |
.align 2 | |
.globl _ZN9factorial9iterativeEi | |
.type _ZN9factorial9iterativeEi, @function | |
_ZN9factorial9iterativeEi: | |
.LFB0: | |
.cfi_startproc | |
.cfi_personality 0x0,__gxx_personality_v0 | |
pushl %ebp | |
.cfi_def_cfa_offset 8 | |
movl %esp, %ebp | |
.cfi_offset 5, -8 | |
.cfi_def_cfa_register 5 | |
subl $16, %esp | |
movl $1, -8(%ebp) | |
movl $2, -4(%ebp) | |
jmp .L2 | |
.L3: | |
movl -4(%ebp), %eax | |
movl -8(%ebp), %edx | |
imull %edx, %eax | |
movl %eax, -8(%ebp) | |
addl $1, -4(%ebp) | |
.L2: | |
movl -4(%ebp), %eax | |
cmpl 8(%ebp), %eax | |
setle %al | |
testb %al, %al | |
jne .L3 | |
movl -8(%ebp), %eax | |
leave | |
ret | |
.cfi_endproc | |
.LFE0: | |
.size _ZN9factorial9iterativeEi, .-_ZN9factorial9iterativeEi | |
.align 2 | |
.globl _ZN9factorial9recursiveEi | |
.type _ZN9factorial9recursiveEi, @function | |
_ZN9factorial9recursiveEi: | |
.LFB1: | |
.cfi_startproc | |
.cfi_personality 0x0,__gxx_personality_v0 | |
pushl %ebp | |
.cfi_def_cfa_offset 8 | |
movl %esp, %ebp | |
.cfi_offset 5, -8 | |
.cfi_def_cfa_register 5 | |
subl $24, %esp | |
cmpl $0, 8(%ebp) | |
jne .L6 | |
movl $1, %eax | |
jmp .L7 | |
.L6: | |
movl 8(%ebp), %eax | |
subl $1, %eax | |
movl %eax, (%esp) | |
call _ZN9factorial9recursiveEi | |
movl 8(%ebp), %edx | |
imull %edx, %eax | |
.L7: | |
leave | |
ret | |
.cfi_endproc | |
.LFE1: | |
.size _ZN9factorial9recursiveEi, .-_ZN9factorial9recursiveEi | |
.ident "GCC: (Debian 4.4.5-8) 4.4.5" | |
.section .note.GNU-stack,"",@progbits | |
*/ | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using std::cout; | |
using std::cin; | |
using std::endl; | |
#include "timer.h" | |
#include "factorial.h" | |
int main() | |
{ | |
timer i_timer; | |
timer r_timer; | |
int n; | |
unsigned long long i_value; | |
unsigned long long r_value; | |
cout << "Enter the value to calculate the factorial of: "; | |
cin >> n; | |
i_timer.start(); | |
i_value = factorial::iterative(n); | |
i_timer.end(); | |
r_timer.start(); | |
r_value = factorial::recursive(n); | |
r_timer.end(); | |
cout << endl << endl | |
<< "With n=" << n << ',' << endl | |
<< " Recursively:" << endl | |
<< " value: " << r_value << endl | |
<< " time : " << r_timer.duration() << endl | |
<< " calculated cost of operations: " << r_timer.duration()/(n * factorial::numberOfRecursiveOperations) << endl | |
<< " Iteratively:" << endl | |
<< " value: " << i_value << endl | |
<< " time : " << i_timer.duration() << endl | |
<< " calculated cost of operations: " << i_timer.duration()/(n * factorial::numberOfIterativeOperations) << endl; | |
#ifdef _WIN32 | |
system("pause"); | |
#endif | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
exe=test | |
ldflags=-lrt | |
ccflags=-O3 -Wall -Wextra | |
cc=g++ | |
.PHONY: all clean | |
all: $(exe) | |
clean: | |
@rm -f *.o | |
@rm -f $(exe) | |
test: main.cpp factorial.o timer.o | |
$(cc) $(ccflags) $(ldflags) $^ -o $@ | |
%.o: %.cpp | |
$(cc) $(ccflags) -c $^ -o $@ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A class that provides a simple timer | |
* Works in Windows and Linux, resolution is hardware dependant | |
* | |
* | |
* Copyleft Gordon Bailey 2012 - All wrongs reserved | |
* | |
* */ | |
#include "timer.h" | |
#ifdef _WIN32 | |
#include <cstdlib> | |
#include <iostream> | |
using std::endl; | |
using std::cerr; | |
timer::timer() : ready(false) { | |
bool success = QueryPerformanceFrequency(&counter_freq); | |
if(!success){ | |
cerr << "Error, QueryPerformanceFrequency failed." << endl; | |
system("pause"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void timer::start() { | |
ready = false; | |
bool success = QueryPerformanceCounter(&start_time); | |
if(!success){ | |
cerr << "Error, QueryPerformanceCounter failed." << endl; | |
system("pause"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void timer::end(){ | |
ready = true; | |
bool success = QueryPerformanceCounter(&end_time); | |
if(!success){ | |
cerr << "Error, QueryPerformanceCounter failed." << endl; | |
system("pause"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
// there is probably some unnecessary typecasting here, but better safe than sorry | |
double timer::duration(){ | |
if (ready){ | |
return 1e6 * (((double)(end_time.QuadPart - start_time.QuadPart)) / ((double)counter_freq.QuadPart)); | |
}else{ | |
return 0; | |
} | |
} | |
#else | |
timer::timer() : ready(false) {} | |
void timer::start() { | |
ready = false; | |
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); | |
} | |
void timer::end(){ | |
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time); | |
ready = true; | |
} | |
double timer::duration(){ | |
if (ready){ | |
return 1e6 * (difftime(end_time.tv_sec, start_time.tv_sec) + (1e-9 * (double)(end_time.tv_nsec - start_time.tv_nsec))); | |
}else{ | |
return 0; | |
} | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef TIMER_H | |
#define TIMER_H | |
#ifdef _WIN32 | |
#include <Windows.h> | |
#else | |
#include <time.h> | |
#endif | |
class timer{ | |
#ifdef _WIN32 | |
LARGE_INTEGER start_time; | |
LARGE_INTEGER end_time; | |
LARGE_INTEGER counter_freq; | |
#else | |
struct timespec start_time; | |
struct timespec end_time; | |
#endif | |
bool ready; | |
public: | |
void start(); | |
void end(); | |
double duration(); | |
timer(); | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment