, 6 min read
Testing COBOLworx gcc-cobol #2
Original post is here eklausmeier.goip.de/blog/2023/02-12-testing-cobolworx-gcc-cobol-p2.
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:
tmpfs 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
mkdir build
cd build
time ../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[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Tasks: 124, 300 thr, 228 kthr; 16 running
2[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Network: rx: 0KiB/s tx: 0KiB/s (5/0 pkts/s)
3[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Load average: 15.40 9.23 4.39
4[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Disk IO: 1.1% read: 0KiB/s write: 7KiB/s
5[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Swp[ 0K/0K]
6[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Mem[|||||||||||||||||||||||| 7.84G/62.2G]
7[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C] Uptime: 04:32:22
8[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
9[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
10[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
11[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
12[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
13[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
14[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
15[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%|4202MHz|88°C]
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
time 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.
/usr/local/gcobol/libexec/gcc/x86_64-pc-linux-gnu/13.0.0$ ldd cc1
linux-vdso.so.1 (0x00007fff5e3a1000)
libisl.so.23 => /usr/lib/libisl.so.23 (0x00007f1908800000)
libmpc.so.3 => /usr/lib/libmpc.so.3 (0x00007f1908a45000)
libmpfr.so.6 => /usr/lib/libmpfr.so.6 (0x00007f1908748000)
libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007f19086a5000)
libzstd.so.1 => /usr/lib/libzstd.so.1 (0x00007f19085fd000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f1908515000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f190832e000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f1908a9b000)
/usr/local/gcobol/libexec/gcc/x86_64-pc-linux-gnu/13.0.0$ ldd cobol1
linux-vdso.so.1 (0x00007ffdc05d6000)
libisl.so.23 => /usr/lib/libisl.so.23 (0x00007fbb52800000)
libmpc.so.3 => /usr/lib/libmpc.so.3 (0x00007fbb52b23000)
libmpfr.so.6 => /usr/lib/libmpfr.so.6 (0x00007fbb52a6b000)
libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fbb5275d000)
libzstd.so.1 => /usr/lib/libzstd.so.1 (0x00007fbb526b5000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007fbb525cd000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fbb523e6000)
/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:
/usr/local/gcobol/bin/gcobol sqrt3.cob
It produces an a.out
file. Change LD_LIBRARY_PATH
:
export LD_LIBRARY_PATH=/usr/local/gcobol/lib64
Running the program shows:
Hello World!
+ 001.000000
+ 001.414213
+ 001.732050
+ 002.000000
+ 002.236067
+ 002.449489
+ 002.645751
+ 002.828427
+ 003.000000
+ 003.162277
+ 003.316624
+ 003.464101
+ 003.605551
+ 003.741657
+ 003.872983
+ 004.000000
+ 004.123105
+ 004.242640
+ 004.358898
+ 004.472135
Source file sqrt3.cob
in question is:
000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. sqrtcob.
000030 AUTHOR. Elmar Klausmeier.
DATE-WRITTEN. 13-May-2009.
DATA DIVISION.
WORKING-STORAGE SECTION.
*01 I PIC 9999999 USAGE COMP-5.
01 I USAGE BINARY-LONG.
01 IMAX USAGE BINARY-LONG VALUE 20.
*01 SQRTI PIC 999.999999999 USAGE COMP-3.
01 SQRTI PIC 999.999999.
01 ARGV PIC X(100) VALUE SPACES.
PROCEDURE DIVISION.
DISPLAY "Hello World!".
* ACCEPT ARGV FROM ARGUMENT-VALUE.
* MOVE ARGV TO IMAX.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > IMAX
* MULTIPLY I BY 2 GIVING SQRTI
COMPUTE SQRTI = FUNCTION SQRT(I)
DISPLAY I " " SQRTI
* DISPLAY I
000250 END-PERFORM.
000270 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:
cobol1: yyparse:4287: no symbol 'ARGUMENT-VALUE' found
cobol1: ARGUMENT-VALUE, sqrt3.cob line 17 at 'ARGUMENT-VALUE'
cobol1: internal compiler error: Segmentation fault
0xde484f crash_signal
../../gcc/toplev.cc:314
0x87b8be cbl_special_name_of
../../gcc/cobol/symbols.h:1274
0x87b8be special_of
../../gcc/cobol/parse.y:1709
0x87b8be yyparse()
../../gcc/cobol/parse.y:4287
0x8b72e6 parse_file
../../gcc/cobol/util.cc:1562
0x8b72e6 cobol_parse_files(int, char const**)
../../gcc/cobol/util.cc:1608
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <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.
$ time cobc -O3 -x xdamcnt.cob
real 0.10s
user 0.08s
sys 0
swapped 0
total space 0
Same procedure with gcc-cobol.
time /usr/local/gcobol/bin/gcobol -O3 xdamcnt.cob
real 0.23s
user 0.22s
sys 0
swapped 0
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
.
$ cobc -v
cobc (GnuCOBOL) 3.2-rc1.0
Built Jan 29 2023 19:33:21 Packaged Jan 18 2023 17:48:17 UTC
C version "12.2.1 20230111"
Version information for gcobol
.
$ /usr/local/gcobol/bin/gcobol -v
Driving: (3)
[0] /usr/local/gcobol/bin/gcobol
[1] -v
[2] -rdynamic
Using built-in specs.
COLLECT_GCC=/usr/local/gcobol/bin/gcobol
COLLECT_LTO_WRAPPER=/usr/local/gcobol/libexec/gcc/x86_64-pc-linux-gnu/13.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/usr/local/gcobol --with-pkgversion='gcc with COBOL front end' --disable-bootstrap --disable-multilib --enable-languages=c,c++,cobol
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc 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.