Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  11:51[Войти] | [Зарегистрироваться]
Ответ на вопрос № 50573

29-03-2007 01:14
Как исправить код, или помогите разобраться в компиляторе.

Заметил странную оптимизацию, у меня если убрать жирную строчку, программа работает быстрее.

Но мне эта строчка очень нужна!

{$APPTYPE CONSOLE}
program Project1;

uses
  Windows,
  Matrix in 'Matrix.pas';

FUnction Oem(const S:String):String;
begin
SetLength(Result,Length(S));
CharToOem(PCHar(s),PChar(Result));
end;

var
TmpTime,Time:LongInt;
i:Integer;

BEGIN
Set8087CW(Get8087CW and $FCFF or $0200);

WriteLn(Oem('Решение системы линейных уравнений методом Якоби'));
TmpTime:=GetTickCount;
For i:=0 to 1000000 do Yakob;
//Yakob;
Time:=GetTickCount;
Dec(Time,TmpTime);
WriteLn(Oem('Посчитан за '),Time/1000:3:2,Oem(' микросекунд'));
WriteLn;
WriteLN(Oem('Решение системы :'));
WriteLn;
For i:=0 to N do
Begin
  Write(i+1:3,' ');
  WriteLn(Res[i]:10:7);
end;
WriteLn;
WriteLN(Oem('С точностью: '),Eps);
WriteLn;
WriteLN(Oem('Сходимость:'));
WriteLn;
For i:=0 to 100 do
begin
end;
Set8087CW(Get8087CW or $0100);
ReadLn;
END.



unit Matrix;

interface
const Eps=1E-7;

const N=14;
type
Sq=array[0..N,0..N+1] of Single;
F=array[0..N] of Double;
const

Mat:Sq  =
  ((26,7.5,2.8,1.4,0,0,0,0,0,0,0,0,0,0,0,-36),
  (7.5,26,7.5,2.8,1.4,0,0,0,0,0,0,0,0,0,0,-179.3),
  (2.8,7.5,26,7.5,2.8,1.4,0,0,0,0,0,0,0,0,0,-23.8),
  (1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,0,0,0,0,0,0,-77.7),
  (0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,0,0,0,0,0,29.3),
  (0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,0,0,0,0,154.7),
  (0,0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,0,0,0,-126.2),
  (0,0,0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,0,0,-155.5),
  (0,0,0,0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,0,32.5),
  (0,0,0,0,0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,0,35.5),
  (0,0,0,0,0,0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,0,253.1),
  (0,0,0,0,0,0,0,0,1.4,2.8,7.5,26,7.5,2.8,1.4,175.6),
  (0,0,0,0,0,0,0,0,0,1.4,2.8,7.5,26,7.5,2.8,138),
  (0,0,0,0,0,0,0,0,0,0,1.4,2.8,7.5,26,7.5,25.4),
  (0,0,0,0,0,0,0,0,0,0,0,1.4,2.8,7.5,26,136.9));

var
Res:F;

Procedure Yakob;

implementation

Procedure Yakob;
var
i,j,k:Integer;
X:Extended;
LastRes:F;
Sum,err,MaxErr:Extended;
begin
Repeat
  LastRes:=Res;
  MaxErr:=0;
  For i:=0 to N do
  begin
    Sum:=0;
    For j:=0 to i-1 do
    begin
      Sum:=Sum+Mat[i,j]*LastRes[j];
    end;
    For j:=i+1 to N do
    begin
      Sum:=Sum+Mat[i,j]*LastRes[j];
    end;
    X:=(Mat[i,N+1]-Sum)/Mat[i,i];
    Err:=Abs(X-LastRes[i]);
    Res[i]:=X;
    if err>MaxErr then MaxErr:=err;
  end;
Until MaxErr<eps;
end;

end.

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

02-04-2007 13:27 | Сообщение от автора вопроса
2 Сабир Сафаров
Конечно Спасибо, но в данном случае скорость не нужна, а нужен алгоритм. Т.к. делаю Лаб. Раб.

02-04-2007 12:16
Про выбранный вами метод: Обратите внимание что у вас разреженная матрица (так называемая пятидиагональная матрица). В таких системах обычно используют  не итерационные методы, а специальные методы прогонки. Поищите в рунете алгоритм прогонки для пятидиагональных матриц - получите существенный выигрыш в скорости. Существенней, чем ассемблерные вставки.

29-03-2007 15:09 | Сообщение от автора вопроса
А можно вопрос перенести в другую тему? Это итерационный метод Якоби, решения матрицы.

29-03-2007 14:01 | Сообщение от автора вопроса
>>>У меня разница вообще в 2.5 раза.
>>>Проверил на стареньком Athlon 1GHz (одна из первых моделей, даже не XP):
Стабильно воспроизводится 9.79/8.06 = 1.21

У меня атлон 3000+ 3.6/2.4 = 1.44. Athlon - rulez :)

29-03-2007 13:51 | Сообщение от автора вопроса
2 DRON
Теперь, все отлично работает.

>>>Да, кстати о птичках... зачем вообще что-то самому конвертировать если можно просто настроить нужную CodePage с помощью SetConsoleOutputCP или вам совместимость с 9х нужна?
Нет не нужна, делал как написано у Anatoly Podgoretsky

Забыл сказать.

Procedure Yakob;
var
i,j:Integer;
X:Double;
LastRes:F;
Sum,err,MaxErr:Double;


Так быстрее и правильнее.

29-03-2007 13:28
На современных процессорах и не такое бывает... дооптимизировались, как говорится. У меня разница вообще в 2.5 раза.

Проверил на стареньком Athlon 1GHz (одна из первых моделей, даже не XP):

Стабильно воспроизводится 9.79/8.06 = 1.21


29-03-2007 13:10
Да, кстати о птичках... зачем вообще что-то самому конвертировать если можно просто настроить нужную CodePage с помощью SetConsoleOutputCP или вам совместимость с 9х нужна?

29-03-2007 13:03
В данном конкретном случае можно сделать как-то так, но вообще по хорошему  это сам Borland должен делать при компиляции.

procedure Yakob;
var
  LastRes:F;
  I,J,K:Integer;
  X:Extended;
  Sum,err,MaxErr:Extended;
begin
  asm
    mov eax,esp
    and esp,$FFFFFFF0
    mov [esp-4],eax
 
end;
  repeat
    LastRes:=Res;
    MaxErr:=0;
    for I:=0 to N do begin
      Sum:=0;
      for J:=0 to I-1 do begin
        Sum:=Sum+Mat[I,J]*LastRes[J];
      end;
      for J:=I+1 to N do begin
        Sum:=Sum+Mat[I,J]*LastRes[J];
      end;
      X:=(Mat[I,N+1]-Sum)/Mat[I,I];
      Err:=Abs(X-LastRes[I]);
      Res[I]:=X;
      if err>MaxErr then MaxErr:=err;
    end;
  until MaxErr<eps;
  asm
    mov esp,[esp-4]
 
end
end;


29-03-2007 12:43
1) Быть такого не может
На современных процессорах и не такое бывает... дооптимизировались, как говорится. У меня разница вообще в 2.5 раза.

А причина банальна: выравнивание. Переменная LastRes расположена на стеке и её точный адрес зависит от того в каком конкретно виде будет стек при вызове вашей Yakob. "Жирная" строчка ни на что не влияет кроме размера локальных переменных (там временная переменная для результата конвертации создаётся), он увеличивается на 4 байта, так что в одном случае функция вызывается со с стеком выравненным по границе 4 байт, а во втором по границе 8 байт. А если верить документации Intel-а скорость чтения/записи невыравненной переменной типа Double почти в два раза медленнее чем выровненной, ну а так как ничего кроме тупой долбёжки этих самых Double вы не делаете, то разница становится заметной на глаз.

29-03-2007 11:12 | Сообщение от автора вопроса
1) Быть такого не может
2) Если все-таки это так, то см. 1)

Сам знаю. Но факт на лицо код работает в 1.44 раза медленее. Это зависит от того сколько раз вызывается Oem() {у меня 5} и неважно где.
Хм а ваш, TPID пример дает тот-же результат что и до этого.
Напишите пожалуйста у кого какие результаты скорости с Oem и без него.
Вообще ошибку можно исправить вызвав дополнительный Oem(' ') без вывода на консоль.

29-03-2007 02:35
1) Быть такого не может
2) Если все-таки это так, то см. 1)
3) Для успокоения совести замените строки

WriteLN(Oem('С точностью: '),Eps);
WriteLn;
WriteLN(Oem('Сходимость:'));



на


WriteLn(Oem('С точностью: '),Eps,#10,#13,Oem('Сходимость:'))


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Кто съел Красную шапочку?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования