Original post is here: eklausmeier.goip.de
Last year in March I tested COBOLworx gcc-cobol. See Testing COBOLworx gcc-cobol. The results were disappointing:
- Simple programs did not compile
- Many COBOL statements were not recognized
- Compiled programs gave entirely wrong results without any indication that something was missing
This post is a follow-up. I was messaged directly by James K. Lowden, one of the developers for COBOLworx gcc-cobol. Development machine is an AMD Ryzen 7 5700G, max. 4.6 GHz clock. In the previous article I used an Intel NUC. So the performance results are not directly comparable.
1. Installation. Download from Git branch master+cobol 4e539299c27d693ecd8f446914cfbc5adf54a14e. Tar.bz2 file is 100 MB. Unpacking into a RAM disk takes 10s. Compilation is now going to happen entirely in RAM disk, i.e., in /tmp
as Arch Linux usually has /tmp
in tmpfs
. Corresponding man-page:
1tmpfs is a filesystem whose contents reside in virtual memory. Since the files on such filesystems typically reside in RAM, file access is extremely fast. See tmpfs(5).
Starting with
1mkdir build
2cd build
3time ../configure --prefix=/usr/local/gcobol --disable-bootstrap --disable-multilib --enable-languages=cobol
Took 1s. This prefix
configuration will install the compiler and its libraries under /usr/local/gcobol
.
Now compile with make -j16
. A joy to see that money spent in memory and CPU was well invested, htop
shows the following:
1 1[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Tasks: 124, 300 thr, 228 kthr; 16 running
2 2[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Network: rx: 0KiB/s tx: 0KiB/s (5/0 pkts/s)
3 3[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Load average: 15.40 9.23 4.39
4 4[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Disk IO: 1.1% read: 0KiB/s write: 7KiB/s
5 5[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Swp[ 0K/0K]
6 6[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Mem[|||||||||||||||||||||||| 7.84G/62.2G]
7 7[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Uptime: 04:32:22
8 8[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
9 9[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
10 10[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
11 11[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
12 12[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
13 13[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
14 14[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
15 15[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
16 16[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
Time needed was 452s = 7.5 minutes, overall CPU consumption was 3565s = 60 minutes.
As root-user I created /usr/local/gcobol
, then chown myuser:myuser /usr/local/gcobol
. I did so because I did not want to install the compiler as root, possibly disturbing the existing gcc
. Finally
1time make install
which took 7s.
So overall, installing the compiler is straightforward. I had some difficulties initially, but they were my own fault: When something goes wrong in the setup, it is best to completely untar the downloaded file and start from scratch, otherwise some left-over config files might disturb the process.
2. Dependencies. The compiler has below dependencies, which you must have installed previously. In most cases they are already installed.
1/usr/local/gcobol/libexec/gcc/x86_64-pc-linux-gnu/13.0.0$ ldd cc1
2 linux-vdso.so.1 (0x00007fff5e3a1000)
3 libisl.so.23 => /usr/lib/libisl.so.23 (0x00007f1908800000)
4 libmpc.so.3 => /usr/lib/libmpc.so.3 (0x00007f1908a45000)
5 libmpfr.so.6 => /usr/lib/libmpfr.so.6 (0x00007f1908748000)
6 libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007f19086a5000)
7 libzstd.so.1 => /usr/lib/libzstd.so.1 (0x00007f19085fd000)
8 libm.so.6 => /usr/lib/libm.so.6 (0x00007f1908515000)
9 libc.so.6 => /usr/lib/libc.so.6 (0x00007f190832e000)
10 /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f1908a9b000)
11/usr/local/gcobol/libexec/gcc/x86_64-pc-linux-gnu/13.0.0$ ldd cobol1
12 linux-vdso.so.1 (0x00007ffdc05d6000)
13 libisl.so.23 => /usr/lib/libisl.so.23 (0x00007fbb52800000)
14 libmpc.so.3 => /usr/lib/libmpc.so.3 (0x00007fbb52b23000)
15 libmpfr.so.6 => /usr/lib/libmpfr.so.6 (0x00007fbb52a6b000)
16 libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fbb5275d000)
17 libzstd.so.1 => /usr/lib/libzstd.so.1 (0x00007fbb526b5000)
18 libm.so.6 => /usr/lib/libm.so.6 (0x00007fbb525cd000)
19 libc.so.6 => /usr/lib/libc.so.6 (0x00007fbb523e6000)
20 /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fbb52b79000)
Libraries in question.
Arch Package | Description |
---|---|
libmpc | Library for the arithmetic of complex numbers with arbitrarily high precision |
mpfr | Multiple-precision floating-point library |
gmp | A free library for arbitrary precision arithmetic |
libisl | Library for manipulating sets and relations of integer points bounded by linear constraints |
3. Compiling COBOL sources. Compiling source code file sqrt3.cob
goes like this:
1/usr/local/gcobol/bin/gcobol sqrt3.cob
It produces an a.out
file. Change LD_LIBRARY_PATH
:
1export LD_LIBRARY_PATH=/usr/local/gcobol/lib64
Running the program shows:
1Hello World!
2+ 001.000000
3+ 001.414213
4+ 001.732050
5+ 002.000000
6+ 002.236067
7+ 002.449489
8+ 002.645751
9+ 002.828427
10+ 003.000000
11+ 003.162277
12+ 003.316624
13+ 003.464101
14+ 003.605551
15+ 003.741657
16+ 003.872983
17+ 004.000000
18+ 004.123105
19+ 004.242640
20+ 004.358898
21+ 004.472135
Source file sqrt3.cob
in question is:
1000010 IDENTIFICATION DIVISION.
2000020 PROGRAM-ID. sqrtcob.
3000030 AUTHOR. Elmar Klausmeier.
4 DATE-WRITTEN. 13-May-2009.
5
6 DATA DIVISION.
7 WORKING-STORAGE SECTION.
8 *01 I PIC 9999999 USAGE COMP-5.
9 01 I USAGE BINARY-LONG.
10 01 IMAX USAGE BINARY-LONG VALUE 20.
11 *01 SQRTI PIC 999.999999999 USAGE COMP-3.
12 01 SQRTI PIC 999.999999.
13 01 ARGV PIC X(100) VALUE SPACES.
14
15 PROCEDURE DIVISION.
16 DISPLAY "Hello World!".
17 * ACCEPT ARGV FROM ARGUMENT-VALUE.
18 * MOVE ARGV TO IMAX.
19
20 PERFORM VARYING I FROM 1 BY 1 UNTIL I > IMAX
21 * MULTIPLY I BY 2 GIVING SQRTI
22 COMPUTE SQRTI = FUNCTION SQRT(I)
23 DISPLAY I " " SQRTI
24 * DISPLAY I
25000250 END-PERFORM.
26
27000270 STOP RUN.
So, line numbering works as it should. But DISPLAY
has problems with showing BINARY LONG
.
Uncommenting ACCEPT ARGV
in above source leads to below error message:
1cobol1: yyparse:4287: no symbol 'ARGUMENT-VALUE' found
2cobol1: ARGUMENT-VALUE, sqrt3.cob line 17 at 'ARGUMENT-VALUE'
3cobol1: internal compiler error: Segmentation fault
40xde484f crash_signal
5 ../../gcc/toplev.cc:314
60x87b8be cbl_special_name_of
7 ../../gcc/cobol/symbols.h:1274
80x87b8be special_of
9 ../../gcc/cobol/parse.y:1709
100x87b8be yyparse()
11 ../../gcc/cobol/parse.y:4287
120x8b72e6 parse_file
13 ../../gcc/cobol/util.cc:1562
140x8b72e6 cobol_parse_files(int, char const**)
15 ../../gcc/cobol/util.cc:1608
16Please submit a full bug report, with preprocessed source (by using -freport-bug).
17Please include the complete backtrace with any bug report.
18See <https://gcc.gnu.org/bugs/> for instructions.
So the compiler crashes if it cannot handle a statement. The above ACCEPT ARGV
is the GnuCobol way of handling command line arguments, it is not official COBOL. So rejecting this statement might be considered correct, but crashing the compiler clearly is not good.
Compiler still has problems with EXIT SECTION
, i.e., it does not understand this statement. So if your source code contains those statements, you have to change them to a go to
to the proper end of the section. This is a little bit annoying.
4. Compilation speed. It seems that GnuCOBOL's cobc
is significantly faster than gcc-cobol.
1$ time cobc -O3 -x xdamcnt.cob
2 real 0.10s
3 user 0.08s
4 sys 0
5 swapped 0
6 total space 0
Same procedure with gcc-cobol.
1time /usr/local/gcobol/bin/gcobol -O3 xdamcnt.cob
2 real 0.23s
3 user 0.22s
4 sys 0
5 swapped 0
6 total space 0
Please take note: This comparison is not entirely fair as gcc-cobol is based on an experimental version of gcc
. Version information for cobc
.
1$ cobc -v
2cobc (GnuCOBOL) 3.2-rc1.0
3Built Jan 29 2023 19:33:21 Packaged Jan 18 2023 17:48:17 UTC
4C version "12.2.1 20230111"
Version information for gcobol
.
1$ /usr/local/gcobol/bin/gcobol -v
2Driving: (3)
3 [0] /usr/local/gcobol/bin/gcobol
4 [1] -v
5 [2] -rdynamic
6
7Using built-in specs.
8COLLECT_GCC=/usr/local/gcobol/bin/gcobol
9COLLECT_LTO_WRAPPER=/usr/local/gcobol/libexec/gcc/x86_64-pc-linux-gnu/13.0.0/lto-wrapper
10Target: x86_64-pc-linux-gnu
11Configured with: ../configure --prefix=/usr/local/gcobol --with-pkgversion='gcc with COBOL front end' --disable-bootstrap --disable-multilib --enable-languages=c,c++,cobol
12Thread model: posix
13Supported LTO compression algorithms: zlib zstd
14gcc version 13.0.0 20221216 (experimental) (gcc with COBOL front end)
5. Performance.
I tried the n-queens problem, see Comparing GnuCOBOL to IBM COBOL. Program name is xdamcnt
. Results are identical for all programs.
xdamcnt
compiled with GnuCOBOL runs in 18 seconds for n=13. Compiled with gcc-cobol it needs 5 minutes. The C program version is xdamcnt2.c.
Compiler | real time / s |
---|---|
gcc | 0.5 |
cobc | 18 |
gcobol | 306 |
So performance of executable for gcc-cobol is terrible.
6. Summary. This COBOL compiler has matured a lot. Though, it is still not production ready, which the authors of the compiler also do not pretend.