Arch_rgz_1
.pdfМинистерство образования и науки РФ Новосибирский государственный Технический Университет
Кафедра ПВТ
Лабораторная работа №1
по дисциплине «Архитектура ЭВМ и вычислительных систем»
Факультет: ПМИ Группа: ПМИ-22 Студенты: Суслов А.В.
Матвеев Т.И. Преподаватель: Маркова В.П.
Новосибирск
2013
Задание №1. Определение времени работы прикладных программ, исследование зависимости времени выполнения программ от уровня оптимизации компилятора.
Условие задачи:
Вычисление числа Пи с помощью разложения в ряд по формуле:
π 4
параметр N – число итераций.
Результаты работы программы (OS Linux, gcc version 4.1.2 20080704)
№ |
Уровень |
Способ измерения |
Величина параметра |
Время работы функции, с |
|
оптимизации |
времени |
прикладного |
|
|
|
|
алгоритма |
|
|
|
|
|
|
1 |
- |
rdtsc |
1000000000 |
13.973894 |
2 |
- |
clock_gettime() |
1000000000 |
12.527948 |
|
|
|
|
|
3 |
- |
утилита time |
1000000000 |
11.398 |
|
|
|
|
|
4 |
-O0 |
rdtsc |
1000000000 |
14.070491 |
5 |
-O0 |
clock_gettime() |
1000000000 |
12.468819 |
|
|
|
|
|
6 |
-O0 |
утилита time |
1000000000 |
11.46 |
7 |
-O1 |
rdtsc |
1000000000 |
13.052217 |
|
|
|
|
|
8 |
-O1 |
clock_gettime() |
1000000000 |
11.857621 |
9 |
-O1 |
утилита time |
1000000000 |
10.185 |
|
|
|
|
|
10 |
-O2 |
rdtsc |
1000000000 |
12.305494 |
11 |
-O2 |
clock_gettime() |
1000000000 |
11.048015 |
|
|
|
|
|
12 |
-O2 |
утилита time |
1000000000 |
10.360 |
|
|
|
|
|
13 |
-O3 |
rdtsc |
1000000000 |
12.159691 |
14 |
-O3 |
clock_gettime() |
1000000000 |
11.043224 |
|
|
|
|
|
15 |
-O3 |
утилита time |
1000000000 |
10.401 |
16 |
-march=i386 |
rdtsc |
1000000000 |
12.466791 |
|
|
|
|
|
17 |
-march=i386 |
clock_gettime() |
1000000000 |
10.848194 |
|
|
|
|
|
18 |
-march=i386 |
утилита time |
1000000000 |
10.07 |
Команды компиляции и запуска:
g++ -o main0 -Wall -lrt main0.cpp
g++ -O0 -o main0v0 -Wall -lrt main0.cpp g++ -O1 -o main0v1 -Wall -lrt main0.cpp g++ -O2 -o main0v2 -Wall -lrt main0.cpp g++ -O3 -o main0v3 -Wall -lrt main0.cpp
g++ -march=i386 -o main0i -Wall -lrt main0.cpp
./main0 -1000000000 > main0.t1
./main0v0 -1000000000 > main0v0.t1
./main0v1 -1000000000 > main0v1.t1
./main0v2 -1000000000 > main0v2.t1
./main0v3 -1000000000 > main0v3.t1
./main0i -1000000000 > main0i.t1
time ./main0 -1000000000 -x > main0.time time ./main0v0 -1000000000 -x > main0v0.time time ./main0v1 -1000000000 -x > main0v1.time time ./main0v2 -1000000000 -x > main0v2.time time ./main0v3 -1000000000 -x > main0v3.time time ./main0i -1000000000 -x > main0i.time
Исходный код программы:
#include <stdio.h> #include <stdlib.h> #include <time.h>
#ifdef WIN32
#define METHODS 1
#else
#include <sys/times.h> #include <unistd.h>
struct timespec tstart1, tend1;
struct tms tstart2, tend2;
long clocks_per_sec = sysconf(_SC_CLK_TCK); long clocks;
#define METHODS 4
#endif
clock_t tm; clock_t t2; union ticks
{
unsigned long long t64;
struct s32 { long th, tl; } t32; } start, end;
double cpu_Hz = 2300000000ULL; // for 2.3 GHz CPU
int tv = 0;
void timerUp()
{
switch(tv)
{
case 0: // clock
tm = clock();
break;
case 1: // rdtsc #ifndef WIN32
asm("rdtsc\n": "=a"(start.t32.th), "=d"(start.t32.tl));
#endif
break;
case 2: // clock_gettime [GNU] #ifndef WIN32
clock_gettime(CLOCK_REALTIME, &tstart1);
#endif
break;
case 3: // times [GNU] #ifndef WIN32
times(&tstart2);
#endif
break;
}
}
float timerDown()
{
float r = 0;
switch(tv)
{
case 0:
t2 = clock();
r = (float)(t2 - tm) / (float)CLOCKS_PER_SEC;
break;
case 1:
#ifndef WIN32
asm("rdtsc\n": "=a"(end.t32.th), "=d"(end.t32.tl)); r = (end.t64-start.t64)/cpu_Hz;
#endif
break;
case 2:
#ifndef WIN32
clock_gettime(CLOCK_REALTIME, &tend1);
r = tend1.tv_sec-tstart1.tv_sec + 0.000000001 * (tend1.tv_nsec-
tstart1.tv_nsec);
#endif
break;
case 3:
#ifndef WIN32 times(&tend2);
clocks = tend2.tms_utime - tstart2.tms_utime; r = (float)clocks / clocks_per_sec;
#endif
break;
}
return r;
}
void setTimingMethod(int a)
{
if(a < 0 || a > METHODS) printf("Method #%d is not available\n", a); else tv = a;
}
double pi_decomp(int N)
{
double r = 4;
for(int i = 1; i < N; i++)
r += 4.0 / (double)(2 * i + 1) * (i % 2 ? -1.0 : 1.0); return r;
}
void timedWork(long d, int a = 0)
{
setTimingMethod(a);
timerUp();
double v = pi_decomp(d);
printf("#%d: Time elapsed: %f sec. [value=%f]\n", a, timerDown(), v);
}
int main(int argc, char *argv[])
{
bool ui = true; bool utime = false; int d = 0;
if(argc >= 2)
{
for(int i = 1; i < argc; i++)
if((argv[1][0] != '-') && (argv[1][0] != '/'))
{
printf("Error: wrong argument (%s)\n", argv[1]); exit(1);
}
d = atoi(argv[1] + sizeof(char));
if(argc >= 3)
{
if(argv[2][1] == 'x') utime = true; // only for utility time
}
ui = false;
}
else
{
printf("Enter a parameter N: "); scanf("%d", &d);
}
if(d <= 0)
{
printf("Error: wrong parameter N\n"); exit(2);
}
if(!utime)
for(int i = 0; i < METHODS; i++) timedWork(d, i);
else
printf("Value: %9f\n", pi_decomp(d));
#ifdef WIN32
if(ui) system("pause");
#endif
return 0;
}