IBM Mainframe Assembler 程序在添加 COBOL 调用后显示 CPU 时间和运行时间的极端跳跃。为啥?可以做些啥来加快速度?

Posted

技术标签:

【中文标题】IBM Mainframe Assembler 程序在添加 COBOL 调用后显示 CPU 时间和运行时间的极端跳跃。为啥?可以做些啥来加快速度?【英文标题】:IBM Mainframe Assembler program shows extreme jump in CPU Time and Run Time after COBOL call added. Why? What can be done to speed it up?IBM Mainframe Assembler 程序在添加 COBOL 调用后显示 CPU 时间和运行时间的极端跳跃。为什么?可以做些什么来加快速度? 【发布时间】:2017-03-09 10:36:18 【问题描述】:

一个读取非常大文件的 IBM Mainframe Assembler 程序被修改为对每条记录调用一次 COBOL“存根”程序。 COBOL 调用是必不可少的,但程序本身做的工作很少。 CPU 的轻微增加自然是意料之中的,但测试显示 CPU 使用率和运行时间的增加非常高。为什么?可以做些什么来加快速度?

足以重现问题的示例源代码:

(1) 一个调用IEFBR14 8192次的汇编程序:

SAMPLE CSECT
       LR    12,15
       USING SAMPLE,12
       LHI   9,8192
LOOP   CALL  IEFBR14
       BCT   9,LOOP
       SR    15,15
       SVC   3
       END

日志显示非常低的资源消耗,在调用什么都不做的程序时是合理的。

EXCP    CPU    SRB  CLOCK   SERV  PG 
  11    .00    .00    .00    603   0

(2) 现在编写一个除了 GOBACK 什么都不做的简单 COBOL 程序:

识别部。 程序 ID。 COBOL. 程序部。回去。

...并且还在同一个循环中调用它 8192 次:

SAMPLE CSECT              
       LR    12,15        
       USING CALLCOB,12   
       LHI   9,8192       
LOOP   CALL  IEFBR14         
       CALL  COBOL        
       BCT   9,LOOP       
       SVC   3            
       END

哟!相比之下,现在资源消耗可怕

 EXCP    CPU    SRB  CLOCK   SERV  PG 
65552    .16    .00    .19  3980K   0 

【问题讨论】:

你确定是 COBOL 程序吗?同样没有看到任何代码,我们怎么能开始猜测效率低下的地方? 或任何之前和之后的统计数据 “你确定它是 COBOL 程序吗?”当然。这个问题很容易重现,并且对于实际修改 IBM Mainframe Assembler 程序以调用 IBM Enterprise COBOL 程序的任何人来说都是显而易见的。 好吧,可以这么说,但您的问题中没有任何内容可以帮助我们帮助您。只是说 CPU 时间增加有点含糊。给我们一些之前和之后的统计数据,给我们一些可以追求的东西。我了解您的目标只是获得代表,但您需要开始发布符合 *** 准则的问题。 删除了我的反对票。现在我们有一个问题。 【参考方案1】:

至少从 1990 年代开始,标准的 IBM COBOL、PL/I 和 Fortran 就包含了一个名为“语言环境”(LE) 的内置功能,它提供了一套标准的运行时可调用服务,这些服务对所有人都是通用的。在运行时,这个“环境”由初始化例程建立,旨在为所有后续的语言间调用提供持久服务。但是虽然汇编程序支持 LE,但它不是自动内置的。因此,当 Assembler 调用诸如 COBOL 之类的“符合 LE 的”语言时,每次调用都会调用这些初始化例程,从而大大减慢了进程。解决方案是让 Assembler “驱动程序”程序建立 LE 运行时环境,因此它会在所有后续调用中持续存在并且只发生一次。值得庆幸的是,这很容易通过向 Assembler 源代码添加一些简单的语句来完成。虽然很少且简单,但放置是至关重要的。以下是一些可用作模板的示例“shell”代码:

SHELL CEEENTRY AUTO=DSALEN 
* COBOL CALL can be anywhere after CEEENTRY and before CEETERM 
       CEETERM ,
* declare constants here: 
CONSTANT DC    CL8'CONSTANT'
PPA    CEEPPA  ,  (P)rogram (P)rolog (A)rea
       CEEDSA  ,  (D)ynamic (S)torage (A)rea
* declare variables here: 
VARIABLE DS    CL8
DSALEN EQU     *-CEEDSA
       CEECAA ,
       END

还有其他与 LE 相关的 Assembler 宏(请参见下面的链接),但以上这些都是简单、高效的 COBOL 调用所必需的。

将基本语句添加到示例程序以使其“符合 LE”后,但保持相同的 IEFBR14/COBOL CALL 循环:

SAMPLE CEEENTRY AUTO=DSALEN                    
       LHI   9,8192                            
LOOP   CALL  IEFBR14                           
       CALL  COBOL                             
       BCT   9,LOOP                            
       CEETERM ,                               
PPA    CEEPPA  ,  (P)ROGRAM (P)ROLOG (A)REA    
       CEEDSA  ,  (D)YNAMIC (S)TORAGE (A)REA   
DSALEN EQU     *-CEEDSA                        
       CEECAA ,                                
       END                                     

...现在资源消耗对于调用一个也不执行任何操作的附加程序再次是合理的:

 EXCP    CPU    SRB  CLOCK   SERV  PG 
   23    .00    .00    .00   1814   0 

z/OS 语言环境编程指南 ... 专门的编程任务 ... 汇编器注意事项 ... 汇编器宏:

http://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/com.ibm.zos.v2r2.ceea200/clcasm5.htm

【讨论】:

语言运行时 (LE) 确实是罪魁祸首,因为原始发布者的方法导致它被加载和卸载数千次。切换到符合 LE 的汇编程序的一个简单替代方法是简单地使用任何 LE 语言编写的“存根”,然后调用您的汇编程序例程。正是出于这个原因,我经常使用一个空的 C 程序,它只包含一个调用链接的汇编程序例程的 main()。

以上是关于IBM Mainframe Assembler 程序在添加 COBOL 调用后显示 CPU 时间和运行时间的极端跳跃。为啥?可以做些啥来加快速度?的主要内容,如果未能解决你的问题,请参考以下文章

IBM Assembler 表搜索

是否可以使用空手道框架连接 IBM Mainframe DB2? [复制]

在 Mainframe 中发送电子邮件的不同方式都有哪些?

如何在 Linux-Assembler 中发出哔哔声?

CoreOS coreos-assembler文档

CoreOS coreos-assembler文档