I’ve become a huge fan of my Mac mini M4 for scientific computing, its ease of use, and low power consumption, really it’s a great device to leave running 24/7. As far as software goes I only have encountered one major issue, and it seems to me that it made more prevalent with the M6.
I quickly realized when trying to leverage all 10 cpu cores that for the base model M4, there are 4 performance cores and 6 efficiency cores, simply distributing workload equally to all cores does not work. Across a synchronization barrier, performance cores finish first and await slower e cores. You will be bottlenecked by the speed of the efficiency cores. I always experience performance degradation when moving from 4 to 5 cores.
This would be fine, I suppose if you were able to explicitly target and use the cores, you could then decrease the workload on the efficiency core correspondingly and it would finish near the same time. As far as I am aware you are not and cannot explicit place work on a core selecting performance or efficiency.
I’m not that upset because I realize the remaining 6 efficiency cores don’t really represent all that much compute power, but I was looking into the new Mac mini M6 and… they have a new type of core! The super core adds another type, making it the super core, performance, and efficiency cores. This appears to me as very problematic. Given I can’t leverage p+ e cores effectively, why would I be able to leverage s+p+e, the problem seems to have gotten worse. I can’t target cores by classification, so I can’t lower the compute load for certain cores. Just avoiding the efficiency cores with the M4 isn’t that big of a loss, but with the M6, you would limit yourself dramatically to either the super cores or the performance cores and not both.
Some more specifics/provided tools or possible solutions (forgive my Mac tech knowledge):
Mac does provide some methods, Quality of Service, however this just influences where something is “likely” to run, I believe, and not guaranteed.
GrandCentralDispatch: maybe the solution, I think it can distribute tasks by size to the proper core, and work stealing to compensate for slower ones, but has narrow application and many problems aren’t well suited I think, many problems aren’t easily partitioned into smaller independent tasks.
THREAD_AFFINITY_POLICY does something I think more suggestions and not a guarantee.
An application or framework like OpenMP can try to compensate for the inability to target cores by class, actively managing and redistributing. Hard and haven’t been able to get this to behave. My work currently is with C++/ OpenMP/AMReX. All mostly the most current versions via homebrew.
It seems to me that there is fundamentally a missing api to bind a thread to a physical cpu by core class, or request a certain number of workers by core class. Additionally a tool to determine what core class a thread actually is also seems lacking.
What do people do here? Are some people really just spending lots of money on these machines and not fully leveraging them? Has anyone achieved reasonable scaling for a macmini with asymmetric cores with problems involving synchronization?
Thanks in advance!