2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1, 2, 3, 4  След.
 
 Re: Быстрое вычисление функции exp(x)
Сообщение28.02.2014, 15:06 
pi-314 в сообщении #831244 писал(а):
1. А что с Real не так ? (повторюсь - не программист ))
Когда-то, очень давно, тип Real был размером 48 бит, и вычислялся программно, т.к. операции с плавающей точкой реализовались в сопроцессорах, да и те были редкостью. Сейчас это уже давно не так.
pi-314 в сообщении #831244 писал(а):
2. Обычный ПК - Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz, Win7 (32 bit)
Нормально. Быстрее специализированной инструкции процессора получится только если сильно ухудшить точность.
pi-314 в сообщении #831244 писал(а):
3. Оказывается в набор инструкций FPU не входит операция вычисления exp(x).
Зато есть возведение в степень двойки и логарифмирование по основанию 2, с одновременным умножением, что, в принципе, одно и то же.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение01.03.2014, 17:21 
rockclimber в сообщении #831289 писал(а):
Сейчас, да еще и во freepascal, легко может оказаться, что тип real является просто алиасом для extended.
И Single, и Double тоже туда-сюда преобразуются. У сопроцессора обычно одна разрядность, а не три. :-) Вроде.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение01.03.2014, 17:51 
arseniiv
Да, x87 FPU содержит восемь 80-битных регистров данных, в которых хранятся числа с плавающей точкой двойной расширенной точности. Когда число (целое, с плавающей точкой или целое в двоично-десятичной кодировке) загружается из памяти в любой из этих регистров, оно автоматически преобразуется в формат с плавающей точкой двойной расширенной точности. Все это написано в параграфе 8.1.2 "x87 FPU Data Registers" тома 1 "Basic Architecture" интеловского "Intel® 64 and IA-32 Architectures Software Developer's Manual" — который лежит по адресу http://www.intel.com/content/www/us/en/ ... nuals.html совершенно открыто и бесплатно.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение01.03.2014, 18:17 

(2 Joker_vD.)

О, спасибо за ссылку!

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение23.03.2014, 17:03 
pi-314 в сообщении #831041 писал(а):
сразу оговорюсь - не программист, не математик, а прикладной гидромеханик.
Задача численного решения системы уравнений мат.физики столкнула с программированием на Free Pascal (в среде Lazarus).

Код написал, численная схема работает, но задача ускорения выполнения программы осложнена медленной работой встроенной в Free Pascal функции для вычисления exp(x).

Несколько запоздалый комментарий, но все же...

Зачем вообще для таких задач использовать Паскаль? Быстродействие exp() - далеко не единственная проблема, которая при этом появится. Пожалуй, наиболее естественный способ - сразу сменить язык на более пододящий для вычислительных задач.

Я сейчас написал три одинаковых программки на Паскале, Фортране и Си. Все три в основном считают экспоненты ($10^8$ раз). Результат прогона с максимальной автоматической оптимизацией на одном ядре выглядит так: FPC - 9.5 секунды, С - от 2.7 до 3.7 секунды (в зависимости от используемого компилятора), Фортран - 2.1 секунды (более-менее одинаково на нескольких приличных компиляторах). Вывод, думаю, очевиден.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение24.03.2014, 09:15 
Pphantom в сообщении #839992 писал(а):
Фортран - 2.1 секунды

Спасибо за численное сравнение !
Подумаю над возможностью перехода на Фортран.
Буду благодарен, если подскажите в какой среде и с каким компилятором рекомендуете начать применять Фортран.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение24.03.2014, 09:47 
pi-314 в сообщении #840193 писал(а):
Буду благодарен, если подскажите в какой среде и с каким компилятором рекомендуете начать применять Фортран.

Я бы посоветовал обойтись без какой-либо среды вообще, но, если очень надо, возьмите, например, Oracle Solaris Studio (бывший SUN Studio). По крайней мере, в ней очень неплохой компилятор, причем с достаточно "жесткими" настройками по умолчанию, что для новичка полезно.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение24.03.2014, 09:49 
Вот результаты моих сравнений fpc и gcc:

test.pas

код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
program Test;

procedure Main();
const
  Delta: Extended = 0.000001;
var
  X: Extended;
  Sum: Extended;
begin
  X := -10.0;
  Sum := 0.0;
  repeat
    if X > 10.0 then Break;
    Sum := Sum + Exp(X);
    X := X + Delta;
  until False;
  WriteLn(Sum);
end;

begin
  Main();
end.
 


test.c

код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <math.h>
#include <stdio.h>

int main()
{
    const long double delta = 0.000001;
    long double x = -10.0;
    long double sum = 0.0;
    for (;;) {
        if (x > 10.0) {
            break;
        }

        sum += expl(x);
        x += delta;
    }

    printf("%Le", sum);
    return 0;
}
 


Код:
$ fpc -iW
2.4.0

$ gcc --version
gcc (Gentoo 4.5.3-r1 p1.0, pie-0.4.5) 4.5.3

$ fpc -O2 test.pas
$ time ./test
2.2026454736202060E+0010

real    0m1.066s
user    0m1.060s
sys     0m0.000s

$ gcc -O3 test.c -lm
$ time ./a.out
2.202645e+10
real    0m1.446s
user    0m1.420s
sys     0m0.020s


$ gcc -O3 -ffast-math test.c -lm
$ time ./a.out
2.202645e+10
real    0m0.720s
user    0m0.710s
sys     0m0.000s


С другой стороны -funsafe-math-optimizations не совсем безопасны.

-- 24.03.2014, 08:53 --

А вообще OpenCL так и просится

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение24.03.2014, 20:44 
Скажите, а вы специально gcc с ключом O3 запускаете, а fpc — только с O2?

Ну и еще можно поиграться с -mfpmath=sse,387 и -mtune

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение25.03.2014, 04:45 
Joker_vD в сообщении #840369 писал(а):
Скажите, а вы специально gcc с ключом O3 запускаете, а fpc — только с O2?


Спросонья не разобрался, увидел slow optimizations и чего-то пришла аналогия с оптимизацией по размеру кода в Turbo Pascal.

Joker_vD в сообщении #840369 писал(а):
Ну и еще можно поиграться с -mfpmath=sse,387 и -mtune


Ни -O3 для fpc, ни эти флаги для gcc как-то ощутимо не влияют.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение25.03.2014, 11:13 
Pphantom в сообщении #840201 писал(а):
Я бы посоветовал обойтись без какой-либо среды вообще, но, если очень надо, возьмите, например, Oracle Solaris Studio (бывший SUN Studio)


работаю под Win7 (32/64 bit), наверно Oracle Solaris Studio не встанет ?

-- 25.03.2014, 11:17 --

mustitz в сообщении #840202 писал(а):
Вот результаты моих сравнений fpc и gcc:

возможно, для адекватности теста реальным объемным расчетам, вывод данных в коде следует прописать и на экран и в файл, разница в скорости может увеличиться...

-- 25.03.2014, 11:19 --

Pphantom в сообщении #839992 писал(а):
(более-менее одинаково на нескольких приличных компиляторах

извините за дилетантский вопрос, а какие компиляторы для FORTRAN считаются приличными ?

-- 25.03.2014, 11:26 --

pi-314 в сообщении #840521 писал(а):
возможно, для адекватности теста реальным объемным расчетам, вывод данных в коде следует прописать и на экран и в файл, разница в скорости может увеличиться...

поясню: в своем коде все массивы переменных типа P [1..N_dx, 1..2] (одномерная задача по Х, расчетная сетка по времени - двухточечная) имеют только два слоя 1..2 по времени для того, чтобы не городить огромный массив при большом кол-ве шагов по времени. Все вычисленные значения для n-го шага по времени сразу выгружаются в файл и заменяются значением с n+1 (наверно, это стандартный прием )).

Поэтому в коде внутри основного цикла стоит обращение к файлу.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение25.03.2014, 11:46 
pi-314 в сообщении #840521 писал(а):
возможно, для адекватности теста реальным объемным расчетам, вывод данных в коде следует прописать и на экран и в файл, разница в скорости может увеличиться...


Я не понял, что мы меряем. Скорость вычисления exp или скорость записи в файл? Конечно, форматирование вывода и файловые операции съедят весь exp с потрохами. И нужно не exp оптимизировать, а SSD диск покупать.

pi-314 в сообщении #840521 писал(а):
поясню: в своем коде все массивы переменных типа P [1..N_dx, 1..2] (одномерная задача по Х, расчетная сетка по времени - двухточечная) имеют только два слоя 1..2 по времени для того, чтобы не городить огромный массив при большом кол-ве шагов по времени. Все вычисленные значения для n-го шага по времени сразу выгружаются в файл и заменяются значением с n+1 (наверно, это стандартный прием )).

Поэтому в коде внутри основного цикла стоит обращение к файлу.


Но мне вообще непонятно, в чем смысл сохранения данных в файл. Достаточно хранить только данные для двух шагов: текущий $n$-й и будущий $n+1$-й. И в конце шага просто поменять указатели.

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение25.03.2014, 11:49 
pi-314 в сообщении #840521 писал(а):
работаю под Win7 (32/64 bit), наверно Oracle Solaris Studio не встанет ?

Хм... не знаю, наверное. Вообще, кстати, это само по себе тоже неразумно, в областях такого рода стандартом de facto является Linux.

pi-314 в сообщении #840521 писал(а):
возможно, для адекватности теста реальным объемным расчетам, вывод данных в коде следует прописать и на экран и в файл, разница в скорости может увеличиться...

Зачем? Производительность дисковой подсистемы в любом случае ниже, Вы так измерите в основном время записи на диск.

pi-314 в сообщении #840521 писал(а):
извините за дилетантский вопрос, а какие компиляторы для FORTRAN считаются приличными ?

Так сказать, в порядке убывания: IFC, PGI Fortran, уже упомянутый SUN'овский, Open64, gfortran, g95. Я для проверки пользовался первым, третим и четвертым, второго нет под руками, пятый и шестой генерируют менее производительный код (хотя FPC все равно и они обгоняют в разы).

pi-314 в сообщении #840521 писал(а):
поясню: в своем коде все массивы переменных типа P [1..N_dx, 1..2] (одномерная задача по Х, расчетная сетка по времени - двухточечная) имеют только два слоя 1..2 по времени для того, чтобы не городить огромный массив при большом кол-ве шагов по времени. Все вычисленные значения для n-го шага по времени сразу выгружаются в файл и заменяются значением с n+1 (наверно, это стандартный прием )).

Почти. :D Обычно все же временная дискретизация результатов больше, чем самого счета, и существенно эффективнее использовать указатели на два слоя, меняя их местами на каждом шаге (чтобы не переписывать каждый раз все данные из одного слоя в другой, это достаточно существенная трата времени).

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение25.03.2014, 12:48 
mustitz в сообщении #840526 писал(а):
Но мне вообще непонятно, в чем смысл сохранения данных в файл

очевидно, что для того, чтобы иметь результаты расчета для каждого наn-го шага или кратного n (если шаг слишком маленький).

-- 25.03.2014, 13:00 --

mustitz в сообщении #840526 писал(а):
Я не понял, что мы меряем. Скорость вычисления exp или скорость записи в файл?

спасибо за корректировку

-- 25.03.2014, 13:05 --

Pphantom в сообщении #840528 писал(а):
Так сказать, в порядке убывания: IFC, PGI Fortran, уже упомянутый SUN'овский, Open64, gfortran, g95

вот тут нашел сравнение скорости для разных компиляторов: http://www.polyhedron.com/pb05-win32-f90bench_SBhtml

 
 
 
 Re: Быстрое вычисление функции exp(x)
Сообщение25.03.2014, 20:09 
Сравнил скорость выполнения нижеприведенного кода в FPC и Delphi 7.
Delphi 7: 1x; FPC: 1.4x.

Код:
program project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Math,
Windows;

procedure Main();
const
  Delta: Extended =  0.0000001;
var
  X: Extended;
  Sum: Extended;
  Data:text;
  t1: int64;
begin
  t1   := gettickcount;
  Assign(Data, 'Data.txt');
  rewrite(Data);
  X := -10.0;
  Sum := 0.0;
  repeat
    if X > 10.0 then Break;
    Sum := Sum + Exp(X)*Delta/Exp(10*X);
    X := X + Delta;
  until False;
  WriteLn(Sum);
  t1 := gettickcount - t1;
  WriteLn(Data,Sum, '  ',t1);
  Close (Data);
end;

begin
  Main();
end.

 
 
 [ Сообщений: 55 ]  На страницу Пред.  1, 2, 3, 4  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group