Atomic Counters in Fortran

In Fortran, we don’t have built-in atomic operations like Go does. However, we can use OpenMP, which provides atomic directives for thread-safe operations. Here’s how we can implement a similar atomic counter in Fortran:

program atomic_counters
    use omp_lib
    implicit none

    integer(kind=8) :: ops = 0
    integer :: i

    !$omp parallel do
    do i = 1, 50
        call increment_ops(1000)
    end do
    !$omp end parallel do

    print *, "ops:", ops

contains

    subroutine increment_ops(n)
        integer, intent(in) :: n
        integer :: j

        do j = 1, n
            !$omp atomic
            ops = ops + 1
            !$omp end atomic
        end do
    end subroutine increment_ops

end program atomic_counters

Let’s break down this example:

  1. We use the omp_lib module to access OpenMP functionalities.

  2. We declare an 8-byte integer ops to represent our counter. This is similar to the atomic.Uint64 in the original example.

  3. Instead of using goroutines, we use OpenMP’s parallel do construct to create multiple threads. Each thread will call the increment_ops subroutine 1000 times.

  4. The increment_ops subroutine contains the atomic operation. We use the !$omp atomic directive to ensure that the increment operation is thread-safe.

  5. After all threads complete their work, we print the final value of ops.

To compile and run this program, you need a Fortran compiler that supports OpenMP. For example, using gfortran:

$ gfortran -fopenmp atomic_counters.f90 -o atomic_counters
$ ./atomic_counters
ops:    50000

We expect to get exactly 50,000 operations. If we had not used the atomic directive, we might get a different number, changing between runs, because the threads would interfere with each other.

Note that Fortran doesn’t have a built-in equivalent to Go’s WaitGroup. The OpenMP parallel construct automatically waits for all threads to complete before continuing execution, so we don’t need an explicit wait mechanism in this case.

While this example demonstrates atomic operations in Fortran, it’s worth noting that for more complex synchronization needs, Fortran also supports other parallel programming constructs through OpenMP, such as critical sections and locks.