OpenMP parallel plugins in a single-threaded Cog VM
Lauren Pullen <[email protected]> Sat, 4 Jul 2026 04:19:55 -0600
| Newsgroups | gmane.comp.lang.smalltalk.squeak.general |
|---|---|
| Message-ID | <[email protected]> |
Hi List,
I've been experimenting with using OpenMP to boost the performance of
primitives in places where arranging to use SIMD is a hassle.
%
~/program/opensmalltalk-vm/building/macos64ARMv8/squeak.cog.spur/Squeak.app/Contents/MacOS/Squeak
./Spur64VMMaker-3756-sq23799.image simdExample2.st
SIMDPlugin example2 "A*B+C".
Size: SIMD: OpenMP: Cogit:
--------- -------------------- -------------------- --------------------
1,000 0:00:00:00.000000816 0:00:00:00.000037184 0:00:00:00.000006640
10,000 0:00:00:00.000002327 0:00:00:00.000029708 0:00:00:00.000066726
100,000 0:00:00:00.000023785 0:00:00:00.000034158 0:00:00:00.000671026
1,000,000 0:00:00:00.000242202 0:00:00:00.000149838 0:00:00:00.006793125
For a hardware instruction like fmadd.2d, SIMD is a clear winner, and
then only loses out marginally to OpenMP under very large vector sizes.
(It's starting at 10 million elements that Squeak starts to have
trouble, first in Cogit, then in bulk primitives as well. It's probably
Mac virtual memory choking on an 80 million byte array.)
In the ray tracer, the computation is a bit more involved than a few
loads and a single fmadd.2d operation. I tweaked the build script to
use -O3 instead of -Os; this is what I get for computing the
intermediate states for a 320x240 pixel view (the argument to the
primitive is the number of hardware threads to use):
[self primIntermediate_compute: 1] benchFor: 2 seconds.
'1,380 per second. 725 microseconds per run. 0 % GC time.' .
[self primIntermediate_compute: 2] benchFor: 2 seconds.
'2,680 per second. 373 microseconds per run. 0 % GC time.' .
[self primIntermediate_compute: 4] benchFor: 2 seconds.
'5,210 per second. 192 microseconds per run. 0 % GC time.' .
[self primIntermediate_compute: 8] benchFor: 2 seconds.
'5,350 per second. 187 microseconds per run. 0 % GC time.' .
[self primIntermediate_compute: 10] benchFor: 2 seconds.
'5,490 per second. 182 microseconds per run. 0 % GC time.' .
Importantly, this doesn't crash the VM! OpenMP ensures that only one
thread actually returns to the interpreter loop, so smalltalk only ever
sees 1 hardware thread accessing object memory.
Squeak-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]