我有一个长期运行的球拍程序 . 执行相同程序的许多实例将有助于更快地找到答案 . (这取决于随机性 . )所以我在24核机器上从命令行执行同一程序的10个实例 . 执行一个实例(在一个核心上)时的平均吞吐量是500次迭代/秒 . 执行10个实例(在10个核心上)时的平均吞吐量降至每个核心100次迭代/秒 . 我希望每个核心看到类似的吞吐量,因为每个执行根本不与其他核心接口 . 有没有其他人遇到这种行为?怎么了?我怎样才能解决这个问题?
-
-
-
-
-
-
-
-
-
-
-
-
-
- 附加信息 - - - - - - - - - - - --------
-
-
-
-
-
-
-
-
-
-
-
-
操作系统:ubuntu 13.10核心:24
每个实例都编写自己的输出文件 . 每分钟大约一次,每个实例将用更新的结果替换相同的输出文件,该结果大约是10行文本 . 所以,我不认为他们遇到了I / O限制 .
根据top,每个核心使用1.5-2.5%的内存 . 运行10核时,使用16 GB,9 GB是免费的 . 没有运行,使用11 GB,14 GB是免费的 .
没有网络请求 .
以下是(当前内存使用)在10个核心(MB)中的3个上在12分钟内除以1,000,000 .
-
核心3:313,48,73,154,292,242
-
核心4:56,245,261,106,229,190
-
核心6:55,238,66,229,275,207
当我运行(当前内存使用)没有任何其他东西时,它返回29 MB .
2 回答
我发现了这个问题 . 我的程序确实使用了太多内存 . 因此,当我同时运行多个实例时,要么所有内容都不适合缓存(可能是L3),要么超出内存带宽 .
我试图找出问题的根源,为什么我的程序使用了这么多内存 . 通过在程序中的许多地方放置(当前内存使用),我发现问题来自算术移位 . 由于这一个操作,内存使用量不知何故立即加倍 .
当x为大且y为正时执行(算术移位x y)时出现问题 . 在这种情况下,我相信结果使用“flonum”(盒装)而不是“fixnum”(未装箱)来表示 .
即使我将结果屏蔽到32位之后,也有些东西阻止了球拍优化,可能是一阶函数 . 我通过屏蔽x修复它,然后将其传递给算术移位,使结果永远不会超过32位数,并解决了问题 . 现在,我的程序使用80 MB而不是300 MB,我的速度提升了!
我想这不是一个真正的答案;它更像是一个不适合评论的猜测和建议 .
从@MarkSetchell给出的列表中,最明显的起点是I / O - 进程是进行网络请求还是共享输入文件?
稍微不那么明显(但是,猜测,在你的情况下更有可能)是记忆 . 如果需要,唯一的实例可以使用所有可用的RAM . 可以? . 由于10个实例共享相同的RAM,它们可能会更频繁地收集垃圾,这会更慢 .
尝试添加类似的东西
并看看随着时间的推移如何绘制 . 例如,它是否以一个值最高?这与系统中的RAM相比如何?
和/或,使用
racket -W "error debug@GC" <your-program>
显示GC的调试级日志信息 .