Программа для измерения времени исполнения типовой задачи.

1.1 Постановка задачи.

Предлагается написать программу для измерения времени исполнения типовой задачи (сортировки массива, поиск минимума, максимума и т.п.) с точностью до 1 мкс.

Вариант задания:

10

Вычисление интеграла методом    трапеций с точностью до eps

e=0.01, 0.001, 0.00001

1.2 Решение
1.2.1 Интерфейс пользователя

clip_image002

1.1.2.2 Текст программы

program Project1;

uses

Forms,

Unit1 in 'Unit1.pas' {Form1},

intfunc in 'intfunc.pas';

{$R *.res}

begin

Application.Initialize;

Application.Title := 'Задача 4.2';

Application.CreateForm(TForm1, Form1);

Application.Run;

end.unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, Mask, AdvSpin, Math;

type

TForm1 = class(TForm)

Memo1: TMemo;

GroupBox1: TGroupBox;

Eps_set: TAdvSpinEdit;

Label1: TLabel;

Label2: TLabel;

Result_Field: TEdit;

Run_Test: TButton;

Times_result: TEdit;

Label3: TLabel;

Label4: TLabel;

CPU_Speed: TEdit;

procedure Run_TestClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

uses intfunc;

{$R *.dfm}

function RDTSC:comp;

var

TimeStamp:record

case byte of

1: (Whole:comp);

2: (Lo,Hi: LongInt);

end;

begin

asm

db $0F, $31

mov [TimeStamp.lo],eax

mov [TimeStamp.Hi],edx

end;

result:= TimeStamp.Whole;

end;

function GetFrequence : longword;

var

Time_Lo, Time_Hi: comp;

begin

Sleep(1);

Time_Lo:= RDTSC;

Sleep(1000);

Time_Hi:= RDTSC;

result:= Round((Time_Hi-Time_lo));

end;

function intSin(x: Double): Double;

begin

Result := sin(x);

end;

procedure TForm1.Run_TestClick(Sender: TObject);

var Time_Lo, Time_Hi: comp;

Freq : longword;

begin

if(Eps_set.FloatValue=0) then exit;

Freq:=GetFrequence;

CPU_Speed.Text:=FloatToStr(RoundTo(Freq/10E8,-2))+' ÃÃö';

Time_Lo:=RDTSC;

Result_Field.Text := FloatToStr(TrapezeInt(0, Pi, Eps_set.FloatValue, intSin));

Time_Hi:=RDTSC;

Times_result.Text:= FloatToStr((Time_Hi-Time_lo)/Freq)+' c';

end;

end.

{ ***Вычисление определенного интеграла методом трапеций с заданной точностью ***

Просто расчет площади под функцией, параметры: a,b - пределы интегрирования, a<=b

eps - допустимая погрешность, практически гарантируется, что расхождение результата

с истинным значением интеграла не превосходит по модулю указанную величину.

intF - подинтегральная функция. Естественно, желательно задавать функции,

интегрируемые в смысле Римана.

Примечание: Несобственные интегралы не считаем,

Проверок на переполнение нет...

**************************************************** }

unit intfunc;

interface

type

TIntFunc = function(X: Double): Double;

function TrapezeInt(a, b: Double; eps: Double; IntF: TIntFunc): Double;

implementation

function TrapezeInt(a, b: Double; eps: Double; IntF: TIntFunc): Double;

var

//S - площадь на предыдущей итерации,

//x - текущее значение аргумента

//base - высота трапеции

//n - число трапеций, удваивается на каждой итерации

S, x, base: Double;

i, n: Integer;

begin

//Сначала приближение одной трапецией

base := b - a;

Result := (IntF(a) + IntF(b)) / 2 * base;

eps := eps / 10; //Вообще говоря, величина делителя зависит от функции

n := 1;

repeat

S := Result;

base := base / 2;

n := n * 2;

//Новая площадь вычисляется на основе старой

Result := Result / 2;

//Ниже - просто вычисляем площади новых трапеций

for i := 1 to n div 2 do

begin

x := a + base * (i * 2 - 1);

Result := Result + IntF(x) * base;

end;

until abs(S - Result) <= eps;

end;

end.

1.2.3 Результаты отладки:

clip_image004

clip_image006

clip_image008

Как видим с увеличением требуемой точности подпрограмма выполняется все дольше.

Предлагаю ознакомиться с аналогичными статьями: