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]