Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.06.2024, 22:50   #11
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 653
По умолчанию

Вроде как работает.
Код:
Function Sqrt64(var a:Int64):LongWord;
asm
  push ebx
  push edi
  push esi

  mov edi, [eax]
  mov esi, [eax+4] {Çàãðóçèëè íà÷àëüíîå ÷èñëî}

  push ebp

  mov ebx, 2147483648
  mov ebp, 0

  @Begin1:
    mov ecx, ebp
    add ecx, ebx
    mov eax, ecx
    mov edx, 0

    mul ecx

    cmp edx, esi
      ja @Big1
      jb @Go1

    cmp eax, edi
      ja @Big1

    @Go1:
    add ebp, ebx

    @Big1:
    shr ebx, 1

    cmp ebx, 0
      ja @Begin1

  mov eax, ebp

  pop ebp
  pop esi
  pop edi
  pop ebx
end;
Параметр var - использовал потому что иначе asm код не работает.

Остаётся понять, оптимален ли этот код?
Kronos913 вне форума Ответить с цитированием
Старый 23.06.2024, 00:26   #12
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,893
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Я открыл system но там его не нашел
Код:
function Sqrt(const X: Extended): Extended;
asm
        FLD     X
        FSQRT
        FWAIT
end;
northener вне форума Ответить с цитированием
Старый 23.06.2024, 15:23   #13
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 653
По умолчанию

Что будет быстрее работать? Мой алгоритм, или
Код:
trunc(sqrt(x))
Kronos913 вне форума Ответить с цитированием
Старый 24.06.2024, 21:41   #14
NetSpace
Участник клуба
 
Аватар для NetSpace
 
Регистрация: 03.06.2009
Сообщений: 1,829
По умолчанию

сделай цикл в миллион шагов и пусть считает корни от 1 до миллиона или все одинаковые бери. засеки время по таймеру.
потом trunc(sqrt(x)) в цикл запихни тот же и снова время засекай.
так в сравнительном анализе и узнаешь, что быстрее.
Программирование - это единственный способ заставить компьютер делать то, что тебе хочется, а не то, что приходится.
NetSpace вне форума Ответить с цитированием
Старый 24.06.2024, 23:52   #15
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 653
По умолчанию

Пришлось даже 100 миллионов раз выполнить каждую функцию, чтобы был нормальный результат
И да - моя алгоритм сработал почти в 2 раза быстрее
Kronos913 вне форума Ответить с цитированием
Старый 25.06.2024, 00:16   #16
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 653
По умолчанию

Сделал больше тестов. И вот что заметил: если число меньше 2^32 - то быстрее работает мой алгоритм
А если больше - то уже быстрее trunc(sqrt)

Но правда я код который выше еще модернизировал как раз на то чтобы было меньше итераций если число небольшое
Kronos913 вне форума Ответить с цитированием
Старый 25.06.2024, 01:28   #17
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,893
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Сделал больше тестов. И вот что заметил: если число меньше 2^32 - то быстрее работает мой алгоритм
А если больше - то уже быстрее trunc(sqrt)
Извините, не верю без доказательств.
northener вне форума Ответить с цитированием
Старый 25.06.2024, 13:29   #18
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 653
По умолчанию

Моя функция Sqrt64 подгружается с юнита. А вот код тестирования

Суммирование корней я сделал потому что не знаю как именно работает оптимизация кода компилятором, потому сделал так чтобы эти данные использовались куда-то - следовательно точно не сокращались при оптимизации.
Так же, Int64 не хотел использоваться как счётчик цикла, потому пришлось его "вручную" прибавлять

Итог (на картинке): с числами до 2^32 мой код работает быстрее, а вот с числами после 2^32 - медленнее

Код:
Function StandartSqrt(const a:int64):LongWord;
begin
  Result:=Trunc(Sqrt(a*1.0));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  a1, a2, b1, b2: Int64;
  d1, d2, d3, i, j, k: longWord;
begin
  b1:=0;
  b2:=0;

  a1:=0;
  a2:=0;

  d1:=GetTickCount;
  For i:=1 to 10000000 do begin
    inc(a1);
    k:=StandartSqrt(a1);
    b1:=b1+k;
  end;
  d2:=GetTickCount;
  For i:=1 to 10000000 do begin
    inc(a2);
    k:=Sqrt64(a2);
    b2:=b2+k;
  end;
  d3:=GetTickCount;
  Label1.Caption:=IntToStr(d2-d1);
  Label2.Caption:=IntToStr(d3-d2);
  Form1.Refresh;

  a1:=4294967296;
  a2:=4294967296;

  d1:=GetTickCount;
  For i:=1 to 10000000 do begin
    inc(a1);
    k:=StandartSqrt(a1);
    b1:=b1+k;
  end;
  d2:=GetTickCount;
  For i:=1 to 10000000 do begin
    inc(a2);
    k:=Sqrt64(a2);
    b2:=b2+k;
  end;
  d3:=GetTickCount;
  Label3.Caption:=IntToStr(d2-d1);
  Label4.Caption:=IntToStr(d3-d2);
  Form1.Refresh;

  Memo1.Clear;
  Memo1.Lines.Add(IntToStr(b1));
  Memo1.Lines.Add(IntToStr(b2));
end;
Изображения
Тип файла: png изображение_2024-06-25_122539274.png (6.5 Кб, 1 просмотров)
Kronos913 вне форума Ответить с цитированием
Старый 26.06.2024, 19:52   #19
NetSpace
Участник клуба
 
Аватар для NetSpace
 
Регистрация: 03.06.2009
Сообщений: 1,829
По умолчанию

теперь запили отдельную библиотеку *.pas и скинь всем в тему. пусть используют, кто занимается расчётами.
и кстати, эту строки b:=b+k; тоже можно сделать через inc() - быстрее будет, там надо через запятую параметр k написать.
Программирование - это единственный способ заставить компьютер делать то, что тебе хочется, а не то, что приходится.
NetSpace вне форума Ответить с цитированием
Старый 26.06.2024, 23:05   #20
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,589
По умолчанию

Цитата:
Сообщение от NetSpace Посмотреть сообщение
b:=b+k; тоже можно сделать через inc() - быстрее будет
Не думаю, что компилятор делает различие между двумя описаниями одного и того же действия. Анализировать сгенерированный код лень, конечно. По логике, там даже не будет вызова процедуры, а in-line вставка. Да и от версии компилятора зависит, видимо.
digitalis вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Необходимо написать "таймер", который будет запускаться при нажатии кнопки "Start", приостанавливаться на "Pause", и сбрасываться на "Reset" billiejean78 JavaScript, Ajax 1 03.09.2021 08:58
Убрать папки "Pictures", "Music", "Видео", "Downloads" из "МОЙ КОМПЬЮТЕР" Бахтиёр1916 Windows 1 05.04.2017 12:53
Нужно пояснить/прокомментировать код программы, или коды функций "Добавить" "Удалить" "Обновить(редактировать" "Поиск" "Период") ZIRASS PHP 4 15.06.2016 14:23
Вычисление квадратного корня вручную 6AZblJlb Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 8 16.11.2011 04:02
Как "натянуть" сайт написанный вручную на CMS ? zlo_999 HTML и CSS 3 01.02.2011 09:57