如何在 SORT 操作中减少 CPU

Posted

技术标签:

【中文标题】如何在 SORT 操作中减少 CPU【英文标题】:How can I reduce CPU in SORT operation 【发布时间】:2018-07-28 11:31:42 【问题描述】:

我正在使用 DFSORT 将磁带数据集复制到临时文件,并处理大约 80000000 条记录。复制数据集需要 3 个小时。 有没有其他方法可以减少 CPU 时间。 建议将非常有帮助。 谢谢你。

    //STEP40  EXEC SORTD                                              
    //SORTIN   DD DSN=FILEONE(0),                           
    //            DISP=SHR                                            
    //SORTOUT  DD DSN=&&TEMP,                                       
    //            DISP=(NEW,PASS,DELETE),                          
    //            DCB=(RECFM=FB,LRECL=30050,BLKSIZE=0),               
    //            UNIT=TAPE                                           
    //SYSOUT   DD SYSOUT=*                                            
    //SYSPRINT DD SYSOUT=*                                            
    //SYSIN    DD *                                                   
         SORT FIELDS=(14,6,PD,A,8,6,PD,A,45,2,ZD,A)                   
         OUTREC IFTHEN=(WHEN=(70,18,CH,EQ,C' encoding="IBM037"'),     
                     OVERLAY=(70:C'  encoding="UTF-8"'))              
         OPTION DYNALLOC=(SYSDA,255)                                  
    /*                                                                

【问题讨论】:

LRECL 真的是30050 ???正如 phunsoft 所说,是否需要将其写入磁带。 Check the attributes of the input file 是的 LRECL 是 30050,我在这个数据集中也有 XML 日期 是recfm=FB,如果是的话应该是??? @NITISHSINGH 这看起来像您之前尝试替换“IBM037”进行编码的示例。每条记录的格式是 1 个 xml 文档吗? 【参考方案1】:

我喜欢诊断这类问题...

每条 30K 的 80M 记录约为 2.5TB,由于您正在读取和写入此数据,因此您正在处理至少 5TB(不包括工作文件的 I/O)。如果我的数学计算正确的话,这三个小时内平均为 500MB/秒。

首先要做的是了解 DFSORT 是否真的主动运行了 3 个小时,或者是否有等待时间的来源。例如,如果您的磁带是多卷数据集,则可能需要等待磁带装载时间。在作业日志消息中查找这一点 - 可能是您 3 小时中的 20 分钟只是在等待安装正确的磁带。

您可能还会遇到 CPU 使用问题增加等待时间。根据您的系统设置方式,您的工作可能只获得一小部分 CPU 时间并等待其余时间。您可以通过查看消耗的 CPU 时间(也在作业日志消息中)并将其与经过的时间进行比较来判断...例如,如果您的作业在 3 小时内获得 1000 CPU 秒 (TCB + SRB),那么您就是在这段时间内平均 9% 的 CPU 使用率。在不同的工作类别中提交您的工作可能会有所不同 - 询问您当地的系统程序员

当然,9% 的 CPU 时间可能不是问题 - 您的工作可能会受到大量 I/O 限制,因此大部分等待时间是等待 I/O 完成,而不是等待更多的 CPU 时间。您真正想知道的是您的等待时间是等待 CPU 访问、等待 I/O 还是其他原因。同样,如果您的本地系统程序员知道如何阅读 RMF 报告,他应该能够帮助您回答这个问题。

接下来要做的是更好地了解您的 I/O,目标是减少需要执行的物理 I/O 操作的总数和/或使每个 I/O 运行得更快一些。

这样想:每个物理 I/O 至少需要 2-3 毫秒。在最坏的情况下,如果您正在读取/写入的这 160M 记录中的每一条都需要 3 毫秒,那么经过的时间将是 160,000,000 X .003 = 480,000 秒,即五天半!

正如另一位响应者所说,blocksize 和 buffering 是你的朋友。由于 I/O 操作的大部分时间归结为触发 I/O 并等待响应,因此“大 I/O”不会比“小 I/O”花费更多时间。通常,您希望执行尽可能少和尽可能大的物理 I/O 操作以缩短运行时间。

根据您使用的磁带设备的类型,您应该能够在磁带上获得多达 256K 的块大小 - 即每个 I/O 7 条记录。您的 BLKSIZE=0 可能已经得到了这个,这取决于您的系统是如何配置的。请注意,虽然这取决于设备,但请注意您的站点是否碰巧使用了将“真实”磁带驱动器映射到磁盘的虚拟磁带产品之一……在这里,超过一定限制 (32K) 的块大小往往会运行得更慢。

不幸的是,缓冲比之前建议的答案更复杂...事实证明,BUFNO 适用于使用 IBM 的 QSAM 访问方法的相对简单的应用程序 - 而这不是 DFSORT 所做的。事实上,DFSORT 非常聪明地处理它的 I/O,它会根据可用内存动态创建缓冲区。不过,您可能会尝试在更大的区域中运行您的作业(例如,您的 JCL 中的 REGION=0),并且您可能会发现 DFSORT 选项,如 MAINSIZE=MAX 帮助 - 请参阅this link 了解更多信息。

至于您的磁盘 I/O(包括那些 SORTWK 数据集),这里也有很多选项。您的 30K LRECL 在很大程度上限制了您可以做的阻塞操作,但是您可以进行各种磁盘调整练习,从使用 VIO 数据集到 PAV(并行访问卷)。关键是,其中很多也是特定于配置的,因此正确的答案将取决于您的站点拥有什么以及它是如何配置的。

但也许最重要的是,在您偶然发现正确答案之前,您不想纯粹地反复试验。如果您想学习,请熟悉 RMF 或您的站点拥有的任何性能管理工具(或找到愿意与您合作的系统程序员)并深入研究。问问自己,瓶颈是什么——为什么这项工作没有运行得更快?然后找到瓶颈,修复它并继续下一个。这些都是非常重要的技能,一旦你了解了基础知识,它就不再像一门黑色艺术,而更像是一个你可以遵循任何事情的系统过程。

【讨论】:

更多关于这个话题的链接***.com/q/51840054/6943197我和你一起解决这样的大问题。 M 的直觉是问题在于他处于阻塞状态并且 I/O 效率低下。建议使用 2 个磁带单元,以提高快速切换以减少时间的可能性。我对 Syncsort 不熟悉,但在下一篇文章中,您会看到 SORTWK 的默认值严重低于指定值。很高兴看到您对附加信息的想法。 @Hogstrom:这里的一个复杂情况是我相信 Syncsort 使用他们自己的 ios 驱动程序而不是“普通”I/O,所以他们不一定像你期望的那样尊重像 BUFNO 这样的东西。 BUFNO 确实是 QSAM 的东西,尽管许多“智能”应用程序看到您已经对其进行了编码并在 BSAM 或 EXCP 处理中使用它——这完全取决于应用程序开发人员。使用 Syncsort,我认为他们使用的策略是“我有多少内存,最有效的使用方式是什么?”...对工作空间(在内存中)、缓冲区等进行排序。因此,您需要的不仅仅是JCL BUFNO - 你需要相应的 SORT 选项。 这很公平@valerie-r。我更关心的是您指出的 I/O。 LRECL 和 FB 特性在我看来是一个重要的瓶颈。我认为假设 XML 文档是真正可变长度的,迁移到 VB 会更有效。如果不是,那么,就是这样。 是的,我同意@Hogstrom 的观点...如果实际数据平均低于当前固定的 30K LRECL,那么转换为 VB/VBS 可能会带来巨大的改进。当然,棘手的部分是转换——我们还没有看到这些记录是如何创建的,并且很可能在该过程的那部分中的某些内容需要更改。我认为 OP 说它们是 XML ......可能固定的记录是用空白或空值填充的 XML 有效负载。并且需要将其更改为仅具有 RDW 中的长度并减去任何填充的有效负载。不过,在我看来,这还是值得的。【参考方案2】:

一些关于提高 I/O 性能的 cmets 应该会改善您的整体运行时间。

    在您的 SORTIN 和 SORTOUT DD 语句中,将以下内容添加到您的 DCB。

来自 IBM 的 MVS JCL Manual,第 143 页。

//SORTIN   DD DSN=FILEONE(0),                           
//            DISP=SHR<b>,DCB=BUFNO=192</b>                                            
//SORTOUT  DD DSN=&&TEMP,                                       
//            DISP=(NEW,PASS,DELETE),                          
//            DCB=(RECFM=FB,LRECL=30050,BLKSIZE=0,BUFNO=192),
//            UNIT=TAPE

我选择了 192,因为这些天在内存方面相对便宜。根据您的环境进行调整。这基本上告诉系统每个 I/O 读取多少块,从而减少与 I/O 操作相关的时间。您可以使用此数字来获得最佳结果。默认值为 5。

BUFNO=buffers指定要分配的缓冲区数量 给 DCB。最大值通常为 255,但可能会更少,因为 区域的大小。注意:不要将 BUFNO 子参数编码为 DCB 子参数 BUFIN、BUFOUT 或 DD 参数 QNAME。

    您可以考虑块大小。输出的块大小似乎很奇怪。确保它针对您要使用的设备进行了优化。对于 TAPE 设备,这应该尽可能大。对于 3480 或 3490 设备,这可能与 65535 一样大。您不指定 LRECL,但指出它的 30050,然后您可以指定 60100 的 BLKZIE,这将是每个块两个记录。提高 I/O 效率。

这里有更多关于 BLKSIZE selection 磁带的信息。


3490 Emulation (VTS)    262144 (256 KB)
3590                    262144 (256 KB) (note: on some older models the limit is  
                                               229376 (224 KB) 262144 (256 KB)
    如果您实际使用 TAPE,最后一个快速提示是指定多个 TAPE 设备。这将允许在安装下一个磁带时写入一个磁带。我在这里也包含了 BUFNO 示例:

//SORTOUT DD DSN=&&TEMP, // DISP=(NEW,PASS,DELETE), // DCB=(RECFM=FB,LRECL=30050,BLKSIZE=0,BUFNO=192), // UNIT=(TAPE,2)

当然,这些优化取决于您的物理环境和 DFSMS 设置。

【讨论】:

感谢您的描述性评论@Hogstrom,我尝试了与您提供的提示相同的方法,但现在每次我得到“WER046A SORT CAPACITY EXCEEDED”【参考方案3】:

既然你写了

...完成需要3个小时...

我猜你真正想要的是减少 运行时间,而不是 CPU 时间。经过的时间取决于许多因素,例如机器配置、机器速度、系统总负载、作业的优先级等。如果没有更多关于环境的信息,很难给出建议。

但是,我看到您正在将排序输出写入临时数据集。我得出结论,还有另一个步骤可以读取该数据。为什么要将这些数据写入磁带?磁盘肯定会更快并减少运行时间。


彼得

【讨论】:

是的,我正在将临时数据集传递给另一个步骤,仅此步骤就需要 3 个小时来执行,所以有没有其他方法,如调优或其他实用程序,以减少执行时间? 你能发布 IEF032I 消息吗?它会告诉我们在 3 小时的执行时间内使用了多少 CPU 时间。 引用:“仅此步骤就需要 3 个小时来执行”。这是模棱两可的。哪一步:复制步骤还是下一步? @NicC 我上面提到的步骤需要三个小时才能执行.. @phunsoft IEF234E K A220,O82247,PVT,JHW807##,STEP40 IEF234E R A230,P68559,PVT,JHW807##,STEP40 IEF233A M A220,M59594,,JHW807##,排序,FORCEX .PRXM.FILE1.G0049V00

以上是关于如何在 SORT 操作中减少 CPU的主要内容,如果未能解决你的问题,请参考以下文章

如何减少 golang tcp 服务器中的 cpu 使用率?

我的多线程游戏一直处于 100% CPU。如何管理线程活动以减少 CPU 负载?

PyQt5 - 如何在使用 QThread 时减少 CPU 使用率(低于 50%)?

如何减少 Tensorflow/Keras 使用的 CPU 数量?

Linux系统下如何查看CPU个数

如何减少golang tcp服务器中的cpu使用?