我在一家科研机构工作,目前我正在进行的任务之一就是运行模拟并将其生成的数据即时输出到硬盘。当我说“即时”时,我的意思是程序本身每秒左右将数据吐出到磁盘。这些模拟完全用单线程 C++ 编写,并在 Mac Pro 上运行。这台 Mac 的相关规格如下:
OSX Version: 10.6.8
Model Name: Mac Pro
Model Identifier: MacPro4,1
Processor Name: Quad-Core Intel Xeon
Processor Speed: 2.66 GHz
Number Of Processors: 2
Total Number Of Cores: 8
Intel Xeon 处理器支持超线程,最多可容纳 8 个虚拟核心
我在一个简单的.sh 文件中执行我的模拟,使用以下语法:
nohup simulation1.o configfile 2> /dev/null > /dev/null &
nohup simulation2.o configfile 2> /dev/null > /dev/null &
等等...
使用 nohup 意味着我远程工作时不需要担心随机断开连接。
当我ps
使用我的 bash 文件运行 10 次模拟后,我发现在 STATE 列中,进程定期从“运行”切换到“卡住”。此外,我预计每个进程的 CPU 使用率为 100%,但每个进程的平均使用率约为 28%。(我预计每个进程的 CPU 使用率为 100%,因为当我只运行其中一个模拟时,CPU 列的最大使用率约为 100%,再加上内核具有超线程。这些模拟对 CPU 的要求非常高。)
有人知道发生了什么吗?具体来说:
- 就“卡住”而言,是什么意思
ps
- 为什么每个进程的 CPU 没有达到最大值?
我将非常感激您的帮助。
答案1
我解决了我的问题。这个问题原来很微妙,但多亏了 Ozair - 他一针见血。我的具体模拟没有读数据非常多(只有初始化参数),但输出计算数据需要花费大量时间。我最初实现的粗糙方法涉及标准 c++,file.open("tobewritten.dat")
即使单独使用也很慢,但当运行多个实例时,各个实例会花费很长时间等待硬盘上的“写入时间”。
我学到了几个具体的教训:
cout << std::endl
使用时刷新缓冲区;如果缓冲区未满,则写入 RAM 的更快操作的利用率就不够理想。使用"\n"
后最后关闭文件。c++ 会在缓冲区已满时将其刷新到磁盘。当同时写入多个海量数据文件(我说的是 GB)时,最好手动指定缓冲区。目前,我将缓冲区设置为 50MB。使用大缓冲区意味着您的系统在 RAM 和 CPU 之间花费更多时间,并且仅以 50MB 的间隔转储到磁盘(慢速位)
甚至不要用它
cout
来写入文件。它比sprintf
及其变体都慢。
使用我上面概述的方法,我已经将每个进程的 CPU 使用率从 28% 提高到了 100%。不再出现“卡住”状态。