一个读取非常大的文件的IBM Mainframe Assembler程序被修改为调用COBOL" stub"每个记录一次程序。 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
Log显示非常低的资源消耗,在调用什么都不做的程序时是合理的。
EXCP CPU SRB CLOCK SERV PG
11 .00 .00 .00 603 0
(2)现在编写一个简单的COBOL程序,除了GOBACK之外什么都不做:
识别部门。
PROGRAM-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
答案 0 :(得分:8)
至少从1990年代起,标准的IBM COBOL,PL / I和Fortran都包含了一个名为"语言环境"的内置功能。 (LE)提供所有人共有的标准运行时可调用服务集。在运行时,这个"环境"由初始化例程建立,旨在提供跨所有后续中间语言调用的持久服务。但是当Assembler 支持 LE时,不会自动内置。因此,当汇编程序调用" LE兼容"如COBOL这样的语言,这些初始化例程用每次调用调用,大大减慢了进程。解决方案是让Assembler" driver"程序建立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相关的汇编程序宏(请参阅下面的链接),但上述内容都是简单,高效的COBOL调用所需的全部内容。
将基本语句添加到Sample程序后,使其符合" LE Compliant",但保持相同的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