一直想尝试自己动手构建一个简单的深度学习训练框架,包括数据读取与处理、PS、NN前后向传播、模型save和load、不同训练方式(offline/online .etc)、指标监控、模型部署等部分, 去深入研究内部深度学习训练框架及horovod、byteps、pslite、tensorflow等框架源码,感觉非常吃力。到底还是C++基础知识太薄弱了,没有系统的去学习过,都是碰到问题了才去查原因,有需求了才去查解决方案,虽然能够搞定手头问题,但是对C++的理解却始终浮于表面,后面将会分两到三篇文章对C++的基础知识点进行梳理,然后结合几个框架,逐步跟大家分享和探讨构建一个全流程的深度学习框架过程中涉及到的一些知识点。
1. 一个C++源文件从文本到可执行文件经历的过程:gcc hello.c -o hello
(一) 预处理阶段:gcc -E hello.c -o hello.i
对源代码文件中文件包含关系(头文件)、预编译语句(宏定义)进行分析和替换,生成预编译文件。
(二) 编译阶段:gcc –S hello.i –o hello.s
将经过预处理后的预编译文件转换成特定汇编代码(编译原理相关,词法分析、语法分析、语义分析等),生成汇编文件
(三) 汇编阶段:gcc –c hello.s –o hello.o
将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件
(四) 链接阶段:gcc hello.o –o hello
将多个目标文件及所需要的库打包连接成最终的可执行目标文件(或库文件以供其他程序使用)
2. .c .cc .cpp .h .hpp .inl 这些后缀名都有什么区别
- C中:头文件后缀名.h, 源文件后缀名.c
- C++中:头文件后缀名.h, .hpp, .hxx, 源文件后缀名.cpp, .cc, .cxx, .C .c++
- .h和.hpp的区别是:*.h里面只有声明,没有实现,而*.hpp里声明实现都有,后者可以减少.cpp的数量,适合用来编写公用的开源库。
- inl 文件是内联函数的源文件。内联函数通常在c++头文件中实现,但有的时候内联函数较多或者出于一些别的考虑(使头文件看起来更简洁等),往往会将这部分具体定义的代码添加到INL文件中,然后在该头文件的末尾将其用#include引入。由此也可以看到inl文件的一个用法的影子——模板函数、模板类的定义代码的存放。
-
.c 后缀名:
- .c 是C语言源代码文件的常见后缀名。
- .c 文件中的代码通常遵循C语言的语法规则和标准库函数。
-
.cc 和 .cpp 后缀名:
- .cc 和 .cpp 都是C++语言的源代码文件的后缀名。
- 这两个后缀名之间没有实际的语法或功能区别,只是一种约定或个人偏好。
- 一些人倾向使用 .cc 后缀来表示纯C++代码,而 .cpp 后缀用于区分一些集成了C和C++代码的文件。但这只是一种推荐的做法,真正的区别在于个人或团队的偏好。
-
.h 和 .hpp 后缀名:
- .h 是C头文件的后缀名,通常包含C语言的函数和变量声明等头文件内容。
- .hpp 则是C++头文件的后缀名,通常包含声明和定义类、模板等C++特有的内容。
- .h 和 .hpp 文件中都可以包含函数、类、宏等定义和声明,不同的是 .hpp 头文件可以使用更多C++特性。
-
.inl 后缀名:
- .inl 是用于内联函数的后缀名,常用于C++中将函数的实现放在头文件中。
- 这样可以在多个源文件中将该头文件包含,且函数不需要在每个源文件中单独进行编译和链接。
- 使用 .inl 后缀名是一种约定,用于区分普通头文件和仅包含内联函数实现的头文件。