К книге
Рассказы о математике с примерами на языках Python и CСтраница 13
100%
Страница 13
13

Время выполнения: 1.04c.

И последний вариант, библиотека ipyparallel:

res = dv.map_sync(test2.get_dividers, values)

print(list(res))

Время выполнения: 0.57c.

Таким образом, по сравнению с изначальным вариантом, мы увеличили скорость расчетов почти в 20 раз, при этом сам код изменять или переписывать практически не пришлось.

В целом, можно предложить следующий алгоритм оптимизации вычислений на языке Python:

1) По возможности, стараться использовать встроенные функции, имеющиеся в библиотеках math, numpy и др. Они уже написаны на C или C++, и работают максимально эффективно.

2) Использовать библиотеку numba, указав в начале функции префикс @numba.jit. Это самый простой и “безболезненный” способ, он чуть увеличит время запуска программы, но скорость расчетов может вырасти в 10 раз. Правда, этот способ не поможет, если код уже состоит только из вызовов встроенных функций из п1. Если же код содержит циклы, условия, другие проверки, то скорость выполнения вырастет значительно.

3) Если скорость расчета нужно еще увеличить, переходим к более тяжелой артиллерии - многопоточности. Используя библиотеку multiprocessing, можно разбить вычисления на несколько ядер процессора - это может увеличить скорость в 2-4 раза. Но важно иметь в виду, что межпроцессное взаимодействие - сама по себе довольно-таки долгая операция, так что делать ее имеет смысл для действительно долго выполняющихся фрагментов кода. Небольшая функция, вызывающаяся много раз в разных потоках, будет работать в итоге даже медленнее за счет дополнительных “накладных расходов”.

4) И наконец, если скорость расчета нужно еще увеличить, можно разбить вычисления на несколько компьютеров в сети, используя библиотеку ipyparallel. Как и в предыдущем случае, заранее следует продумать структуру алгоритма, чтобы производить вычисления крупными блоками, это сделает метод более эффективным.

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

Приложение 4 - Тестирование программы на языке Fortran-90

Язык Фортран всегда считался специализированным для математических вычислений. Его первая версия появилась в IBM еще в 1957 году, более-менее современными версиями являются Fortran 90 и Fortran 2003.

Поскольку и сейчас существует версия gfortran под Linux и OSX, стало интересно сравнить быстродействие программ. Отдельного компьютера с Linux у меня не было, так что программа была запущена на Raspberry Pi. Один и тот же код без проблем компилировался и под Linux и под OSX.

В качестве теста использовалась несложная программа вычисления числа Пи по формуле Валлиса.

Программа на С выглядит так:

Appendix4_test1.c

#include <stdio.h>

double wallis_formula(unsigned long int count)

{

double pi = 1.0, num;

unsigned long int i;

for (i=1; i<=count; i++)

{

num = 4.0*i*i;

pi *= num/(num - 1);

}

return pi*2;

}

int main() {

unsigned long int input_count = 100000000;

double result = wallis_formula(input_count);

printf("Calc done: %.20f\n", result);

return 0;

}

Программа, переписанная на Fortran 90 выглядит немного непривычно, если не сказать, архаично:

Appendix4_test1.f90:

function wallisSeries() result(pi)

real(8) :: pi

real(8) :: num

integer :: ITERATIONS = 100000000

pi = 1.0

do i = 1,ITERATIONS

num = 4.0*i*i

pi = pi*num/(num - 1)

end do

pi = 2*pi

end function

program hello

real(8) :: wallisSeries

print *, "Calc done:", wallisSeries()

end program hello

Впрочем, несмотря на другой синтаксис, основная структура кода та же.

Ключи компиляции также похожи:

gcc -o Appendix4_test1_c Appendix4_test1.c -Ofast

gfortran -o Appendix4_test1_f Appendix4_test1.f90 -Ofast

Результаты запуска обеих программ оказались весьма интересными.

Raspberry Pi

$ gfortran -o Appendix4_test1_f Appendix4_test1.f90 -Ofast

$ time ./Appendix4_test1_f

Calc done: 3.1415926364809641

real 2.222s

$ gcc -o Appendix4_test1_c Appendix4_test1.c -Ofast

$ time ./Appendix4_test1_c

Calc done: 3.14159264306626218044

real 3.441s

Как можно видеть, программа на Си оказалась где-то на 30% медленнее. Все-таки более простой код Fortran позволяет легче получить более эффективный код. Но на OSX с gcc последней версии все оказалось по-другому.

OSX

$ time ./Appendix4_test1_f

Calc done: 3.1415926364809641

real 0.788s

$ time ./Appendix4_test1_c

Calc done: 3.14159264306626218044

real 0.434s

Тут уже наоборот, Си вырвался вперед. Возможно, более современный компилятор создает более эффективный код, также возможно, что более эффективно используются команды современных процессоров. Второе интересное отличие - значения в крайних знаках Пи отличаются, видимо реализация расчетов с плавающей точкой в двух языках слегка отличаются (те, кто читал главу 24, поймут в чем дело).

Из всего этого следует несколько выводов. Фортран все-таки устаревший язык, и в общем случае, переписывать программу с Си на Фортран, надеясь ее ускорить, смысла нет - прироста производительности не будет. По читаемости и удобству написания кода Фортран тоже проигрывает - все-таки прогресс в создании компиляторов за последние 20 лет весьма значителен. Но с другой стороны, использование Фортран может быть целесообразно на каких-то специализированных устройствах, если современные компиляторы недоступны. Или в тех случаях, когда уже есть большое количество готовых библиотек, которые в противном случае, пришлось бы переписывать.

Заключение

На этом данная книга закончена, хотя надеюсь, что не навсегда - по возможности и по мере появления новых идей, новые главы будут дописываться. Автор надеется, что хоть немного удалось познакомить читателей с увлекательным миром математики и программирования.

Продолжение следует.

Обо найденных неточностях или дополнениях просьба писать на электронную почту dmitryelj@gmail.com. Наличие новой версии можно проверить на странице https://cloud.mail.ru/public/4SGE/oE2EGEWnp.

Предыдущая главаГлава 13 из 13К книге