-
Notifications
You must be signed in to change notification settings - Fork 30
Open
Description
1、功能描述
当你使用srun启动一个任务时,Slurm的slurmstepd守护进程会在计算节点上启动你的程序。它会创建一个管道 (pipe) 来捕获程序的stdout和stderr,然后将这些输出转发回调用srun的终端。因为程序的stdout现在是连接到一个管道,而不是一个交互式终端,glibc会自动将其设置为全缓冲。如果你的程序是逐步产生输出的(例如,每完成一步计算就打印一行日志),你将无法实时看到这些输出。所有的输出都会被暂存在缓冲区里,直到程序结束或者缓冲区被填满时,你才会一次性地看到所有结果。这对于调试和实时监控作业进度非常不便。
--unbuffered 的作用:
--unbuffered 或 -u 参数告诉srun改变其I/O处理方式。它不再使用标准的管道,而是为你的任务分配一个伪终端 (Pseudo Terminal, PTY)。当你的程序在PTY中运行时,它会“认为”自己正在与一个交互式终端对话。因此,glibc会自动将stdout的缓冲模式切换为行缓冲。
总结:
- 默认 (srun my_app): stdout -> pipe -> 全缓冲 -> 输出延迟,最后集中显示。
- 使用 (srun -u my_app): stdout -> PTY -> 行缓冲 -> 输出实时,每行(遇到\n)都会显示。
2、输出交错
- 这是使用-u时最常见的问题。当你有多个任务(srun -n > 1)并且它们都实时输出时,来自不同任务的输出行会严重混合交错在一起,导致输出难以阅读。
- 解决方法:
- 添加任务号前缀: 修改你的程序,让每一行输出都以任务ID(如Slurm_PROCID环境变量)作为前缀。Slurm提供了--label选项来自动完成这件事,它会在每一行输出前加上任务号:。
参考文档:https://slurm.schedmd.com/srun.html
调研文档:https://e26ruh1viz.feishu.cn/wiki/XVfowM0tjii6GNk8RNHcVKWQn3g
Metadata
Metadata
Assignees
Labels
No labels