代码讲解
模块名:time_cpu
源文件:time_cpu_mod.f
这里面定义了三个函数:
- wall_time
获取当前现实时间 主要调用的是SYSTEM_CLOCK - get_cpu_time
获取当前CPU时间, 主要调用的是cpu_time - remaining_wall_time_estimate
计算距离算完大约还剩余多少时间
get_cpu_time
先看第二个函数get_cpu_time
仅仅就用了下fortran内置函数cpu_time
这个函数是在MFiX-20版本新加的
其实在19版本里面直接就调用的cpu_time
也不知道新加的意义何在
用法:
call CPU_TIME(CPU_NOW)
update_dashboard.f里面有个例子
call CPU_TIME(CPU_NOW)
参数CPU_NOW就是用来存储时间变量的自定义的变量
此外,module run里面有个TIME共享变量,记录程序开始时间。
注意,这个CPU_TIME统计的精度是s,但是可以有小数位。
但是最大的缺点在于:
CPU占用率会影响该时间,并行也会(会统计每个核心的时间并且加起来)!
这就导致这个时间很不准
wall_time
其中DBLE是类型转换为double
SYSTEM_CLOCK是Fortran内置函数,用法如下
来自
http://blog.sina.com.cn/s/blog_14ece821b0102xsiy.html
time_cpu_mod.f中计算wall_time()时就使用了语句
2021-4-30
后文补充了system_clock的具体用法代码
无需引入任何模块,直接调用call system_clock(t1)即将当前时刻存储到了整数t1当中
在结束时刻 再次调用call system_clock(t2)即存储t2时刻
然后t2-t1即为程序耗时。为一整数,单位是毫秒,因此想要表示s要除以1000.0
用count除以count_rate就是当前时间
但是由于计时变量能存储的数值是有上限的,所以还需要加上达到上限的次数乘达每次到上限的消耗的时间。
用法:
前面导入模块
use time_cpu
后面调用函数
mytime=wall_time()
一个wall_time计时的例子
借鉴legacy_test/tfm/Absorption_column_2d/usr1.f中的用法
导入模块
use time_cpu, only: WALL_START
use time_cpu, only: WALL_TIME
定义当地变量
DOUBLE PRECISION:: TICK, TOCK
计时
TICK = WALL_TIME()
...程序代码若干...
TOCK = WALL_TIME()
然后用TICK-TOCK就得到了消耗时间
remaining_wall_time_estimate
2020-10-30补充讲解remaining_wall_time_estimate
这句是重点
est_remaining = (WALL_TIME() - WALL_START)*(TSTOP-TIME)/(TIME-TIME_START)
理清对应的变量就知道他在算什么了
变量名 | 意义 |
---|---|
TIME | 模拟的当前时刻,如2.1秒 |
TSTOP | 模拟设定的结束时刻,如20秒 |
TIME_START | 模拟的开始时刻,如0秒 |
WALL_TIME() | 当前的现实时刻 |
WALL_START | 模拟开始时的现实时刻 |
举个例子,一个瞬态算例,从0秒算到20秒,目前算了2.1秒,从晚上19点算到目前19点半
那么上面的公式就对应着
第一项WALL_TIME() - WALL_START
当
前
现
实
时
刻
−
开
始
的
现
实
时
刻
=
已
过
的
现
实
时
间
19
点
半
−
9
点
=
半
个
小
时
当前现实时刻-开始的现实时刻=已过的现实时间\\ 19点半-9点=半个小时
当前现实时刻−开始的现实时刻=已过的现实时间19点半−9点=半个小时
第二项(TSTOP-TIME)
模
拟
设
定
的
结
束
时
刻
−
模
拟
开
始
时
刻
=
模
拟
剩
余
的
时
间
20
秒
−
2.1
秒
=
17.9
秒
模拟设定的结束时刻-模拟开始时刻=模拟剩余的时间\\ 20秒-2.1秒=17.9秒
模拟设定的结束时刻−模拟开始时刻=模拟剩余的时间20秒−2.1秒=17.9秒
第三项(TIME-TIME_START)
模
拟
当
前
时
刻
−
模
拟
开
始
时
刻
=
模
拟
已
经
算
完
的
时
间
2.1
秒
−
0
秒
=
2.1
秒
模拟当前时刻-模拟开始时刻=模拟已经算完的时间\\ 2.1秒-0秒=2.1秒
模拟当前时刻−模拟开始时刻=模拟已经算完的时间2.1秒−0秒=2.1秒
第一项除以第三项就是:
已
过
的
现
实
时
间
/
模
拟
已
经
算
完
的
时
间
=
平
均
算
1
秒
需
要
的
现
实
时
间
半
小
时
/
2.1
秒
=
857
现
实
秒
/
模
拟
秒
已过的现实时间 / 模拟已经算完的时间= 平均算1秒需要的现实时间\\ 半小时/2.1秒=857 现实秒 /模拟秒
已过的现实时间/模拟已经算完的时间=平均算1秒需要的现实时间半小时/2.1秒=857现实秒/模拟秒
最后再乘以第二项模拟剩余的时间就得到了剩余时间需要算多长现实时间
平
均
算
1
秒
需
要
的
现
实
时
间
×
剩
余
的
模
拟
时
间
857
现
实
秒
/
模
拟
秒
×
17.9
模
拟
秒
=
15342
现
实
秒
=
约
4
小
时
15
分
钟
平均算1秒需要的现实时间×剩余的模拟时间\\ 857 现实秒 /模拟秒 ×17.9模拟秒=15342现实秒=约4小时15分钟
平均算1秒需要的现实时间×剩余的模拟时间857现实秒/模拟秒×17.9模拟秒=15342现实秒=约4小时15分钟
实操: 输出传热量的时刻
目标:看看输出传热量的时刻是不是同一个时刻。
请先看之前输出传热的那篇博客,本文是对它进行改进
https://blog.csdn.net/weixin_43940314/article/details/108569647
添加代码
在每一个源文件前面都添加
USE discretelement, only: des_usr_var
USE time_cpu, only: wall_time
在每一个输出的后面都用一次wall_time()
分别存储到13~18中
des_thermo_newvalues.f
calc_force_dem.f
calc_collision_wall_mod.f
calc_thermo_des.f
des_thermo_rad
结果
时刻还是存储到des_usr_var当中
从左到右依次为:
颗粒编号,
总传热计算时间,
导热计算实际,
与墙壁导热计算时间(因为没开墙壁导热所以没计算),
对流换热计算时间,
反应热计算时间,
辐射热计算时间
总传热计算时间减去导热计算时间
(最后一行可能是因为输出的时候还没计算出导热时间所以是0?)
关注最后一列:总传热计算时间减去导热计算时间
发现其他几项都还好,导热相差时间很大!
计算总传热量和计算导热的时间差了几十秒
最后一列:总传热计算时间减去导热计算时间
看来需要更改一下导热部分
额外再看下总传热时间减去对流计算时间
总传热时间减去反应热计算时间
总传热时间减去辐射计算时间
补充2021-4-30 system clock的用法
无需引入任何模块,直接调用call system_clock(t1)即将当前时刻存储到了整数t1当中
在结束时刻 再次调用call system_clock(t2)即存储t2时刻
然后t2-t1即为程序耗时。为一整数,单位是毫秒,因此想要表示s要除以1000.0
program main
implicit none
integer:: t1,t2,time_cal
character:: sth
call system_clock(t1)//把当前时刻记录到整数t1中,单位为毫秒
read(*,*) sth//相当于C中的sth=getchar()
call system_clock(t2)//把当前时刻记录到整数t2中,单位为毫秒
time_cal=t2-t1
write(*,*) 'This program spent ', time_cal/1000.0, ' sec'
end program main
补充 TIME
补充1
/home/ubuntu1/MFiX_cases/misc/MFiX_sources/mfix-20.4.0/model/
中发现
可见run模块的time变量就是simulation time
补充2
/home/ubuntu1/MFiX_cases/misc/MFiX_sources/mfix-20.4.0/model/output_manager.f
中发现
可见get_cpu_time()即WALL_NOW
而WALL_NOW-WALL_START即当前已过现实时间
而time变量和get_cpu_time()函数的作用是一样的,在module time_cpu中有
可见time这个变量就是存储了get_cpu_time()的值
补充3
另外time_cpu_mod.f中定义了WALL_TIME()函数
补充4
另有remaining_walltime_estimate()代表剩余现实时间
其中该函数位于模块
补充5
相关模块所在源文件
time_cpu_mod.f
output_manager.f
run_mod.f
physical_prop.f
测试
在usr1.f中添加如下语句
得到结果如图所示
可见GUI中与TUI中输出结果完全一致
(多次重复输出是因为采用了并行)
最终用法总结
use time_cpu, only: wall_time, wall_start, time_start
use run, only: time
write(*,*) 'wall time now= ', wall_time()-wall_start
write(*,*) 'sim time now= ', time-time_start
第一行即自模拟开始已过的现实时间
第二行即自模拟开始已经模拟了的模拟时间
其中time也可以换成get_cpu_time()
源代码
链接:https://pan.baidu.com/s/1VODCZ3xwgG3s3Vwkp3hCrg
提取码:nqcs
复制这段内容后打开百度网盘手机App,操作更方便哦