Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 |

 

  Вопрос: Сколько операций нужно для... Добавлено: 24.04.05 19:07  

Автор вопроса:  Страшный Сон
Кто знает, сколько операций выполняет комп для вычисления функций sin, cos и т. п.?

Ответить

  Ответы Всего ответов: 30  

Номер ответа: 1
Автор ответа:
 Morpheus



Вопросов: 224
Ответов: 3777
 Web-сайт: xury.zx6.ru
 Профиль | | #1
Добавлено: 24.04.05 19:24
1) mov листок бумаги to стол
2) mov карандаш to руки
3) mov линейку to руки
4) mov транспортир to руки
5) draw треугольник on листе бумаги
6) unload линейку
7) unload транспортир
8) unload арандаш
9) mov калькулятор to руки
10) поделить нужный катет на гипотенузу
11) unload калькулятор
12) определить знак результата
13) return результ

итого: 13 опреаций :)))))))))

Ответить

Номер ответа: 2
Автор ответа:
 Yura



ICQ: 34372249 

Вопросов: 3
Ответов: 8
 Профиль | | #2 Добавлено: 24.04.05 19:24
Дизасемдлируй программу(лучше под дос, тк там мусора поменьше) и посчитай.

Ответить

Номер ответа: 3
Автор ответа:
 Morpheus



Вопросов: 224
Ответов: 3777
 Web-сайт: xury.zx6.ru
 Профиль | | #3
Добавлено: 24.04.05 19:30
а если серьёзно есть вот такие функции (Delphi+Asm), может пригодятся:

function Tan(const X: Extended): Extended;
{ Tan := Sin(X) / Cos(X) }
asm
        FLD X
        FPTAN
        FSTP ST(0) { FPTAN pushes 1.0 after result }
        FWAIT
end;

function CoTan(const X: Extended): Extended;
{ CoTan := Cos(X) / Sin(X) = 1 / Tan(X) }
asm
        FLD X
        FPTAN
        FDIVRP
        FWAIT
end;

function Secant(const X: Extended): Extended;
{ Secant := 1 / Cos(X) }
asm
        FLD X
        FCOS
        FLD1
        FDIVRP
        FWAIT
end;

function Cosecant(const X: Extended): Extended;
{ Cosecant := 1 / Sin(X) }
asm
        FLD X
        FSIN
        FLD1
        FDIVRP
        FWAIT
end;

Ответить

Номер ответа: 4
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #4
Добавлено: 24.04.05 21:49
Вот тебе с интелоовских мануалов описание. Сколько тактов не сказано (или я не нашёл), а сколько операций см. ниже.


8.3.7. Trigonometric Instructions
The following instructions perform four common trigonometric functions:
FSIN Sine
FCOS Cosine
FSINCOS Sine and cosine
FPTAN Tangent
FPATAN Arctangent
 These instructions operate on the top one or two registers of the x87 FPU register stack and they return their results to the stack. The source operands for the FSIN, FCOS, FSINCOS, and
 FPTAN instructions must be given in radians; the source operand for the FPATAN instruction is given in rectangular coordinate units.
 The FSINCOS instruction returns both the sine and the cosine of a source operand value. It operates faster than executing the FSIN and FCOS instructions in succession.
 The FPATAN instruction computes the arctangent of ST(1) divided by ST(0), returning a result in radians. It is useful for converting rectangular coordinates to polar coordinates.


FSIN Replace ST(0) with its sine.
 Computes the sine of the source operand in register ST(0) and stores the result in ST(0). The source operand must be given in radians and must be within the range -2^63 to +2^63.

IF ST(0) < 2^63 THEN
C2 = 0;
ST(0) = sin(ST(0));
ELSE (* source operand out of range *)
C2 = 1;
FI:

[b]FCOS Replace ST(0) with its cosine.[/b]
 [i]Computes the cosine of the source operand in register ST(0) and stores the result in ST(0). The source operand must be given in radians and must be within the range -2^63 to +2^63.[/i]
[code]
IF |ST(0)| < 2^63 THEN
C2 = 0;
ST(0) = cosine(ST(0));
ELSE (*source operand is out-of-range *)
C2 = 1;
FI;


FSINCOS Compute the sine and cosine of ST(0); replace ST(0) with the sine, and push the cosine onto the register stack.
 Computes both the sine and the cosine of the source operand in register ST(0), stores the sine in ST(0), and pushes the cosine onto the top of the FPU register stack. (This instruction is faster than executing the FSIN and FCOS instructions in succession.)
 The source operand must be given in radians and must be within the range -2^63 to +2^63


IF ST(0) < 2^63 THEN
C2 < 0;
TEMP = cosine(ST(0));
ST(0) = sine(ST(0));
TOP = TOP - 1;
ST(0) = TEMP;
ELSE (* source operand out of range *)
C2 = 1;
FI:


FPTAN Replace ST(0) with its tangent and push 1 onto the FPU stack.
 Computes the tangent of the source operand in register ST(0), stores the result in ST(0), and pushes a 1.0 onto the FPU register stack. The source operand must be given in radians and must be less than ±2^63.

IF ST(0) < 2^63 THEN
C2 = 0;
ST(0) = tan(ST(0));
TOP = TOP - 1;
ST(0) = 1.0;
ELSE (*source operand is out-of-range *)
C2 = 1;
FI;


FPATAN Replace ST(1) with arctan(ST(1)/ST(0)) and pop the register stack.
 Computes the arctangent of the source operand in register ST(1) divided by the source operand in register ST(0), stores the result in ST(1), and pops the FPU register stack. The result in register ST(0) has the same sign as the source operand ST(1) and a magnitude less than +р.
 The FPATAN instruction returns the angle between the X axis and the line from the origin to the point (X,Y), where Y (the ordinate) is ST(1) and X (the abscissa) is ST(0). The angle depends on the sign of X and Y independently, not just on the sign of the ratio Y/X. This is because a point (.X,Y) is in the second quadrant, resulting in an angle between р/2 and р, while a point (X,.Y) is in the fourth quadrant, resulting in an angle between 0 and .р/2. A point (.X,.Y) is in the third quadrant, giving an angle between .р/2 and .р.


ST(1) < arctan(ST(1) / ST(0));
PopRegisterStack;

Ответить

Номер ответа: 5
Автор ответа:
 Morpheus



Вопросов: 224
Ответов: 3777
 Web-сайт: xury.zx6.ru
 Профиль | | #5
Добавлено: 25.04.05 00:22
2CyRax
А по-моему количество тактов зависит от конкретной модели процессора.
Я просто где то читал давно давно, что разные процессоры выполняют одну и ту же операцию за разное количесво тактов :-/
А вообще, имхо не нужно знать абсолютное значение количества операций, чтобы оптимизировать прогу на скорость, достаточно знать относительную скорость тех или иных процедур и функций, чтобы выбрать самую быструю.

Ответить

Номер ответа: 6
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #6
Добавлено: 25.04.05 00:30
Имхо vb'шный вариант синуса может сильно отличаться по скорости от того же сишного, т.к. наверняка там вначале идут проверки на соот-е типов и преобразования.
Чтобы точно посчитать количество операций, я бы заюзал функции о использовании которых Рихтер писал (QueryPerfCounter&GetProcIOCounter, точнее надо в ApiView'ре смотреть). Они для замера времени, которое проц тратит на выполнение твоего процесса (или потока, не помню счас точно), но может он и такты где-нить считает.
А даже если и не считает, то можно это дело вычислить, высчитав время операции, для которой заведомо известно количество тактов и разделив на неё время выполнения синуса или косинуса.

Ответить

Номер ответа: 7
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #7
Добавлено: 25.04.05 00:35
Согласен с Morpheus'ом.
Процы имеют разные наборы инструкций (слышал что AMD'шные особенно быстро работают с плавающими) и следовательно старые процы не могут делать за один такт то, что может новый и тогда наверное это как-то эмулируется и время увеличивается...

Ответить

Номер ответа: 8
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #8
Добавлено: 25.04.05 01:36
 Сопроцессор имеет 3 типа данных: 2 целочисленных, 3 дробных и BCD. Число загружается ы сопроцессор из памяти и после завершения расчётов возвращается в память обратно.
 Из этого следует что при выполении одной операции выигрыша в скорости никак не будет. Будет разве что удобство работы с дробными числами через сопроцессор. Схематически выполение операции сопроцессора можно представить так:
 1. Загрузить число из памяти
 2. Выполнить операцию(ции)
 3. Вернуть результат в память.
 Как видно из схемы, из 3-х операций 2 работают с памятью. Соответственно прирост в скорости можно получить лишь если между пунктом 1 и 3 выполняется несколько вычислений.


 т.к. наверняка там вначале идут проверки на соот-е типов и преобразования.

 Во первых это верно только для типа Variant. Кто тебе мешает использовать вещественные типы данных.
 А во вторых, я хоть немного и знаком с его структурой, но всё равно не берусь делать таких легкомысленных заключений. Тип Variant - это ни что иное как 16-байтный UNION, где первые 8 байт определяют как будут интерпретироваться вторые 8 байт. К примеру если у тебя в Variant'е лежит Double, то первые 8 байт содержат информацию что во вторых 8-ми байтах храняться данные в формате Double. Преобразований тут никаких делать не надо, просто указывай источником указатель на данные, хранящиеся во вторых 8-ми байтах. Время может отнимать только проверка служебной информации из первых 8-ми байт.
 Про преобразование целых/дробных типов тоже не могу сказать однозначно, ведь в сопроцессор можно загружать и целые числа. Я думаю это зависит от конкретной ситуации.

 Могу посоветовать только проверить на практике какой код генерирует компилятор. Дизассемблируй экзешник и смотри что там как.

Ответить

Номер ответа: 9
Автор ответа:
 Страшный Сон



Вопросов: 46
Ответов: 848
 Профиль | | #9 Добавлено: 25.04.05 17:17
Сопроцессор имеет 3 типа данных: 2 целочисленных, 3 дробных и BCD.


Может 3 целочисленных и 2 "дробных"?

Выходит, для вычисления синуса достаточно одной инструкции... А сколько в ней тактов - не ясно. Хотя я могу провести исследование... И безо всякого дисасма.

Ответить

Номер ответа: 10
Автор ответа:
 Morpheus



Вопросов: 224
Ответов: 3777
 Web-сайт: xury.zx6.ru
 Профиль | | #10
Добавлено: 25.04.05 17:36
А как по мне дык если разговор идёт о целочисленных типах то проц всё вычисляет в Extended (ну это в делфи так называется) а все остальные типы придуманы просто чтобы сэкономить память.
Может я чё то не так понял, в киижке по Делфи так писалось :-/

Ответить

Номер ответа: 11
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #11
Добавлено: 25.04.05 18:16

Может 3 целочисленных и 2 "дробных"?

 Может быть, сечас мануалов нет, но могу дома посмотреть. Во всяком случае грузятся целые из памяти длиной WORD/DWORD PTR, а дробные WORD/DWORD/QWORD PTR.


Хотя я могу провести исследование... И безо всякого дисасма.

 Попробуй. Тем более что узнать количество тактов дизассемблер тебе никак не поможет ;)

Ответить

Номер ответа: 12
Автор ответа:
 Страшный Сон



Вопросов: 46
Ответов: 848
 Профиль | | #12 Добавлено: 25.04.05 18:16
все остальные типы придуманы просто чтобы сэкономить память.


Ни фига, для выполнения расчетов с целыми числами и с плавающей точкой используются совсем разные инструкции для проца.

Тут какая-то фигня вышла - по проведенному мной исследованию вычисление функции sin требует порядка 160-170 тактов камня. Многовато это по моему...

Ответить

Номер ответа: 13
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #13
Добавлено: 25.04.05 18:18

проц всё вычисляет в Extended (ну это в делфи так называется) а все остальные типы придуманы просто чтобы сэкономить память.

 Ошибочное мнение. Как раз сопроцессору не всё равно. Тип числа влияет на размер мантисы в регистре сопроцессора.

Ответить

Номер ответа: 14
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #14
Добавлено: 25.04.05 18:22

Ни фига, для выполнения расчетов с целыми числами и с плавающей точкой используются совсем разные инструкции для проца.

 На самом деле в начале инструкции идёт специальный код, определяющий принадлежность её к сопроцессору (Сейчас не вспомню, но по моему это 11011).

Ответить

Номер ответа: 15
Автор ответа:
 Morpheus



Вопросов: 224
Ответов: 3777
 Web-сайт: xury.zx6.ru
 Профиль | | #15
Добавлено: 25.04.05 18:23
Страшный Сон
Согласен, просто я же уточнил что
>если разговор идёт о целочисленных типах


Кстати, а как думаете что будет, если создать матрицу 100x100, заполнить её как таблицу пифагора и при умножении одно-двузначных чисел брать знаечение оттуда?
Например 34*2 = matrix(32,2) ' и всё!!!

по моему, если в проге используется куча операций перемножения, то выигрыш при вытаскивании из матрицы будет заметен по сравнению с обычным перемножением. тем более что матрицу можно и 1000 на 1000 забацать :)

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам