Thursday, October 18, 2012

Multithreading under Cygwin

A while ago, I found a nasty Cygwin bug that prevents all multithreaded applications from working properly under multi-core/thread CPUs. This includes any CPUs with more than one logical core as seen by Windows (e.g. Dual / Quad core CPUs with or without Hyperthreading as well as Single core CPUs with Hyperthreading). It's such a fundamental flaw with Cygwin that virtually renders all multithreaded applications useless since most PCs these days have at least 2 logical cores (8 is common).

Multi logical core CPUs are nothing new. The first Hyperthreaded CPU was a Pentium 4 Northwood (all Northwood CPUs had Hyperthreading although it was only the later steppings that Intel marketting decided to enable the feature for the consumer market) and that dates back to January 2002. That's more than 10 years the Cygwin bug went unnoticed!

How did a Cygwin bug as enormous as that survive 10 years in the wild, still without a fix in sight?

I see a few possibilities.

1) No one does anything of production quality under Cygwin (at least not multithreaded ones).
2) Someone noticed it but just thought Cygwin's naturally slow due to its "emulation" layer.
3) Someone noticed it and reported it but no one cared.
4) Someone noticed it and did not have the technical know-how to root cause it to a Cygwin issue.

Then again, it's not really surprising. Microsoft Windows 64-bit OSes have a WOW64 bug that plagued them since XP and is still not fixed.

The workaround

While there's no way to get a multithreaded app to fully utilize a multicore processor, you could at least get it to run as fast as on a single core processor. To do this, you would have to set your CPU affinity for the Cygwin process to a single logical CPU.

You could do this via the Task Manager - right-click on an Image Name under the Processes tab and select Set Affinity. If you need to start the Cygwin process with it bound to a single logical core from the very beginning, you could use the Start command. It has an affinity option (/AFFINITY 1). However, this only works in Windows Vista and later. You would need to use Microsoft Sysinternal's psexec on WinXP.


Figataur said...

I've just ran into this as well. It's a real shame because for what I'm doing it basically renders Cygwin useless. Heck, even phones have 4 cores these days, so doe to Moore's law now operating in #cores rather than MHz Cygwin will be a curiosity within 18 months unless it is fixed...

Anonymous said...

I spent a lot of time setting up my cygwin environment with SDL2 as the final intention to utilize all of my 8 cores with real time ray tracing.

I have to admit I was really frustrated to notice that single thread 60 FPS dropped down to 1FPS with 8 threads. The CPU usage never went above 10% with Windows 8. Spent hours of looking for the problem in my code before I found your blog post.

I'm now looking for some other environment which would work as easily. Maybe Qt Creator with MinGW...


Anonymous said...

GCC lacks multithreaded programming it's not a bug basically put GCC sucks Cygwin is GCC on Windows basically and Mingw is a smaller cutdown version of Cygwin. Get LLVM instead it requires visual c++ build tools with .net framework 4.5.1, don't remove Mingw on Windows it works as a library for LLVM. Simply point your text editor/ide to Clang instead of Mingw. And yes LLVM has multithreaded support and it's under BSD license.