如何在bash脚本中获取所运行C程序返回的double类型运行时变量值
问题根源说明
Linux/UNIX 系统中进程的退出状态码只能是 0~255 的 8 位无符号整数,C 语言标准也明确规定 main 函数的返回值必须为 int 类型,你返回的 double 类型运行时间会被强制截断为整数,所以无法通过 $? 获取正确的浮点值。
可行解决方案
下面是两种常用的实现方式,你可以根据自己的场景选择:
方案1:捕获程序标准输出(推荐)
将运行时间输出到标准输出,bash 直接捕获该输出即可,其他日志/调试信息可以输出到标准错误流避免干扰。
修改C程序代码
#include <stdio.h> // 如果是MPI程序,记得引入mpi.h int main(int argc, char** argv) { double run_time; // 你原有程序的运行逻辑,计算得到run_time // 其他非运行时间的输出都打印到stderr,避免干扰结果捕获 // fprintf(stderr, "程序运行日志:xxx\n"); // 仅将运行时间打印到stdout fprintf(stdout, "%.10f\n", run_time); // MPI场景下需要加判断,仅让rank 0进程打印结果,避免多进程输出冲突 /* int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { fprintf(stdout, "%.10f\n", run_time); } */ return 0; }
修改bash脚本逻辑
# 先捕获单线程运行时间 t1=$(mpirun -n 1 ./my_program) echo "单线程运行时间:$t1" # 循环测试其他线程数,计算加速比 for (( j=2; j<9; j++ )) do tj=$(mpirun -n $j ./my_program) # 借助bc工具计算浮点加速比(bash本身不支持浮点运算) speedup=$(echo "scale=6; $t1 / $tj" | bc) echo "线程数:$j,运行时间:$tj,加速比:$speedup" done
如果你的程序本来就有大量内容需要输出到标准输出,可以给运行时间加特殊标记过滤:
- C代码中改为
fprintf(stdout, "MY_RUN_TIME:%.10f\n", run_time); - bash捕获时改为
t1=$(mpirun -n 1 ./my_program | grep 'MY_RUN_TIME:' | cut -d':' -f2)
方案2:写入临时文件读取
如果标准输出、标准错误都被业务逻辑占用无法修改,可以把运行时间写入临时文件,bash跑完后读取即可。
修改C程序代码
#include <stdio.h> int main(int argc, char** argv) { double run_time; // 原有运行逻辑计算run_time // MPI场景同样加rank 0判断,避免多进程写文件冲突 FILE* fp = fopen("/tmp/my_prog_runtime.tmp", "w"); if (fp != NULL) { fprintf(fp, "%.10f", run_time); fclose(fp); } return 0; }
修改bash脚本逻辑
# 跑单线程程序,读临时文件拿运行时间 mpirun -n 1 ./my_program t1=$(cat /tmp/my_prog_runtime.tmp) # 后续计算加速比的逻辑和方案1一致
内容的提问来源于stack exchange,提问作者marti
相关产品推荐
相关产品推荐

