ðŸ“˜ Atomic operations in Perl 6

# ðŸ“˜ Atomic operations in Raku

N. B. Perl 6 has been renamed to Raku. Click to read more.

Using the solution for Task 38,Â the Monte Carlo method, create a program that calculates the result using multiple threads.

Perl 6 has built-in support for parallel computing. In Task 92,Â Sleep Sort, weâ€™ve seen how to use the keywordsÂ await,Â gather, andÂ take to spawn a few threads and wait for them to finish.Â

When different threads want to modify the same variable, such as a counter, it is wise to introduce atomic operations to make sure the threads do not interfere with each other. Here is the modification of the Monte Carlo program calculating the area of a circle with four parallel threads.

my atomicint \$inside = 0;

my \$n = 5000;
my \$p = 4;

await gather for 1..\$p {
take start {
for 1..\$n {
my @point = map {2.rand - 1}, 1..2;
\$insideâš›++ if sqrt([+] map *Â², @point) <= 1;
}
}
}

say 4 * \$inside / \$p / \$n;

Run the program a few times, changing the value ofÂ \$n (the number of random points per thread) andÂ \$p (the number of threads). The program should print the value that is close toÂ pi, such asÂ 3.141524.

The new thing here is the atomic increment operation:

\$insideâš›++

An atomic operation ensures that the variable is modified with no conflicts between the threads.

The variable itself should be a native integer of a special typeâ€”notice how it is declared:

my atomicint \$inside;

As the atomic operation uses the Unicode character, there is an ASCII alternative:

atomic-fetch-inc(\$inside)

Hereâ€™s a list of other atomic operations and their synonyms that can be used with parallel processes:

\$var âš›= \$value       atomic-assign(\$var, \$value)
my \$a = âš›\$var         my \$a = atomic-fetch(\$var)

\$varâš›++               atomic-fetch-inc(\$var)
\$varâš›--               atomic-fetch-dec(\$var)
++âš›\$var               atomic-inc-fetch(\$var)
--âš›\$var               atomic-dec-fetch(\$var)