, 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:

  1. Simple programs did not compile
  2. Many COBOL statements were not recognized
  3. 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.