- Main函数在哪里? 对Makfile文件不是特别熟悉了解, 代码发布者把makefile文件写得很有层次感, 很嵌套,让人找起来很费时, 刚开始看到复杂的Makefile文件一脸懵逼. 觉得随便找找看可能更方便, 然而linpack中的HPL中生成的可执行文件为xphl, 别说同名的就类似的.c文件都没有, 作为一个习惯了在上层高级语言编程,习惯了使用IDE的老一代C#码农来说, linux下的C开发缺少类似的项目管理工具, 很不适应.
返回头来, 从Makefile 文件中,发现hpl目录下有两个makefile文件,一个是Make.top, 另一个是Make.test, 即我们之前编辑的arch架构为test的对应文件. 其中在前者中
include了后者, 所以后者中定义的变量, 在前者也是可见的.
而在Makefile中通过make –f 的方式,指定make指令执行的哪一个makefile文件。
你看,你看,这里用的是Make.top
总体看就是make时,Makefile->Make.top->Make.test
这套的,你只能感觉:嗯……逻辑层次很强,
Makefile.test文件中定义了一些后面会用到的变量: 如目标架构名称:
HPL相关的各种路径 :
MPI的相关路径 :
数学库BLAS的路径:
编译器的路径:
2. Make的 command是:make arch=test
这里的arch=test实际上是给变量arch赋值为test,会作用到Makefile中,因为Makefile文件中有用到这个arch变量。
这里的install依赖 startup refresh build 三项。
而startup由之后的命令生成。Make –f命令后指定了执行的是Make.top文件中的
Startup_dir 项,并且参数项
将arch的值传递到Make.top中的arch中那么我们现在转到Make.top中的
项,如下:
意为在创建相关的文件夹路径,包括在include下创建test目录,创建lib目录并在lib目录下创建test目录,创建bin目录,并在bin目录下创建test目录。
接下来是
刚开始不明白leaf是什么意思,以为是make相关命令还是什么,楞查也没查到,在Make.top文件后面发现
这才恍然大悟,原来这里的leaf类似于clean的伪目标项,比如make clean就是执行clean操作,清除相关的文件,而make –leaf 则就是执行leaf下定义的相关命令操作。
后面的都不过是对有关变量的赋值语句而已。转入文件路径下,在该路径下创建test文件夹。
转入到src/auxil/test/路径下
LN_S在Make.test中被赋值为ln –s 该命令为为某个文件创建链接。
所以即将hpl/Make.test 文件创建一个链接文件到当前路径,即src/auxil/test/Make.inc
后面的分析与以上类似。
3.
这两项refresh执行的是文件的拷贝工作。可以看出,作者将功能性的代码和工程性的代码分隔开。又是结构化,层次化,模块化的思想体现的淋漓尽致,软工真的是very nice。
而我们通常在代码开发完成后的优化工作中才做这些工作,最后才发现有时候代码写的关联性耦合性极强,像一团浆糊,已经相当无奈了。
4. Build的过程
转入相应的文件夹路径,执行各自的make,生成相应的目标文件,最终是要生成一个库文件libhpl.a 如何实现的呢? 找啊找啊,没一下看出来,于是查看了makes文件下的每个makefile文件,在
中有发现:
我们知道最后生成的可执行文件的名字为xphl,现在这个字样终于出现了!,有没有好激动!找了so long time,我只觉得比较惨, dumass!
现在看它是怎么生成的, 根据依赖项,看这
此处的变量LINKER,LINKFLAGS 都能在Make.test中找到。
这条指令执行的是链接,将这两个链接在一起,生成为最终的输出文件,$HPL_pteobj在本makefile中定义的,即为:
那么后面的$HPL_LIBS 是什么呢? 它在Make.test文件中被赋值过。
我们可以看到,它由三项组成,
HPLlib 其实是hpl 的库文件
LAlib 其实是GotoBLAS的库文件
MPIlib其实是MPI的库文件,这里用的是openmpi
GotoBLAS与MPI的库都是在各自编译的时候生成的,那么HPL的库在编译的时候怎么生成的呢?目前我们并没有看到其生成过程。
但我们此处已经知道了xhpl是如何生成的了,稍微值得欣慰一点。那么接下来寻找传说中的libhpl.a 是如何生成的?
查看makes文件夹下的其他makefile文件,比如这个Make.blas文件会发现,有这么一段:
变量HPL_blaobj指的是目标文件,如上图所示,变量ARCHIVERARFLAGS以及$HPLlib 在Make.test文件中都有赋值。
由此可看出,要执行的命令实际上是: ar r (LIBdir)/libhpl.a(HPL_blaobj)
ar 是什么命令,后面的r又是啥意思呢?
参见:http://blog.csdn.net/xljiulong/article/details/7082960
现在我们知道了ar是创建库的命令,r表示向库中插入模块,也就是说,会将后面的那些HPL_dcopy.o, HPL_daxpy.o, HPL_dscal.o 等作为模块插入到libhpl.a库文件中。
由此可以知道,这些文件中如果也有相似的段落,
也会将生成的相应的.o文件插入到libhpl.a库文件中,一步一步,逐渐生成完整地libhpl.a文件,我们前面看到的代码的模块化,无论是src下的 还是testing下的 ,都是将各自模块的.o文件在各自文件夹下的makefile编译的时候,通过ar 命令利用参数选项r,插入到libhpl.a库中。
前面说过,看到了xhpl字样,那么顺着它寻找我们的main函数,先找到对应的那个makefile文件,/home/zgz/sourcecode/linpack/hpl/testing/ptest/test下的Make.ptest文件。
可以看到,链接时,除了库文件外,还有一些目标文件,对应的是紫色的部分。
那么main函数在哪里呢?打开对应的.c文件看一下吧。有没有感到连灵魂都在颤抖?
呃。。。其实,它真的就在HPL_pddriver.c中!!!
另外在comm文件夹下,有
而在grid文件夹路径下,有
可以看出,这两处的文件,跟MPI通信的定义和实现有关,因此修改程序时,重点关注。
墨菲定律,有可能出错的,一定会出错。
事情花费的时间永远比你计划的要长。
这是代码修改的一小步,却不是论文发表的一大步,任重道远,别TM墨迹!