V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
sjlinger
V2EX  ›  Python

Python 调用自己编写的 Fortran 函数,会比直接运行 Fortran 程序慢很多么?

  •  1
     
  •   sjlinger · 2019-03-20 13:35:36 +08:00 · 1936 次点击
    这是一个创建于 1856 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在学习 Python 调用 Fortran,期间碰到一个很费解的问题,具体如下:

    1,Fortran 编写了一个三重循环,前两个循环是在循环一个二维数组,第三场循环是每个二维数组的点会循环一个数量为 5000 的离散点,并计算其与离散点的距离,当距离小于一定阈值时,加 1,具体代码如下:
    do i=1,1401
    do j=1,1201
    glat=(j-1)*0.1
    glon=(i-1)*0.1
    do ll=1,5000
    distance=sqrt((glat-lat(ll))**2+(glon-lon(ll))**2)
    if ( distance<= 2.5 ) then
    grid_nst(j,i)=grid_nst(j,i)+1
    endif
    enddo
    enddo
    enddo
    这个如果用 Fortran 编译器编译并直接运行,时间为 13-15s 不等

    2,同一个循环,写成一个 subroutine,然后用 f2py 编译,并用 Python 调用,时间却长达 40-50s 不等,代码未做任何改变,因此只给出传参的代码下:
    Fortran:subroutine test(nst,lat,lon)
    Python:var=loop.test(lat,lon)
    编译命令:f2py -c tt.f90 -m loop --f90exec=gfortran

    同一个循环程序,两种运行方式用时差别如此之大,真的让人想不通,不知有没有懂这两种语言并这么使用过的同志知道原因,谢谢
    justou
        1
    justou  
       2019-03-20 16:59:53 +08:00
    从你的 @ 过来; 如果你把 fortran 源码,什么编译器, 编译参数, 性能测试代码; 以及 python 的代码全部放上来这个问题就完美了, 大家也好根据你的步骤直接试试能不能复现这个性能差距. 你这样问还是只能靠瞎猜.

    我只有两点建议: 1. 保证两边用同样的 fortran 编译器, 同样的编译参数 2.用不同规模的数据去试试差距有多大. f2py 生成 wrapper 肯定是有性能损耗的, 正常情况下, 在数据量小的时候主要损耗在 wrapper 上面, 数据量大的时候性能差距应该很小.
    sjlinger
        2
    sjlinger  
    OP
       2019-03-20 18:06:51 +08:00
    @justou 不好意思,说的还是简单了,我再补偿下,Fortran 代码主要的就是上面这些了,其它的就是读文件里的数据给 lat 和 lon,已经定义变量了,其它的没有更多了,我也是怕会生成额外的计算耗时,所以不敢加多余的语句。编译器和编译代码都一样,编译器是 gfortran,Python 的代码也是读了赋给 lat 和 lon 的外就是 var=loop.test(lat,lon),剩下的就是 Fortran 函数自己去算了,但好像这个论坛上传不了文件,所以再现没大有可能。如果您愿意,咱们可以加个好友,我把数据文件发您,您在您那测一下,我肯定感激不尽。
    附上个我测试 f2py 的性能数据:
    real-time: 49.16020 #这是 Python 调用 Fortran 函数时,我计算的函数内部运算的耗时,
    如果是允许 Fortran 编译器编译的,是 13.66936 这么长时间

    /-----------------------\
    < F2PY performance report >
    \-----------------------/
    Overall time spent in ...
    (a) wrapped (Fortran/C) functions : 49705 msec
    (b) f2py interface, 1 calls : 113 msec
    (c) call-back (Python) functions : 0 msec
    (d) f2py call-back interface, 0 calls : 0 msec
    (e) wrapped (Fortran/C) functions (actual) : 49705 msec

    Use -DF2PY_REPORT_ATEXIT_DISABLE to disable this message.
    Exit status: 0
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5671 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:51 · PVG 09:51 · LAX 18:51 · JFK 21:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.