Multithreaded slower (despite Hyper-Threading)!

Started by
26 comments, last by CGameProgrammer 19 years, 4 months ago
UPDATE: The post below is obsolete. I have a Pentium 4 with Hyper-Threading (SMP) so I made one part of my code multi-threaded to get a speed-up. Two threads are created, each of which evaluates roughly equal amounts of data. In Linux this gave me a nice ~50% increase in framerate, but in Windows it actually decreases -- single-threaded, it's 17 fps, but multi-threaded, it's 11 fps. The threads do not write to the same memory, though each thread does read from memory that the other thread writes to, without any sort of mutex (the order of the read/write is irrelevant). I don't know if that somehow causes a slowdown. My code for creating the threads looks like: [removed] AIThread is the function, ThreadData is the parameter passed, and SimTime is initialized to zero, and set to some value when the thread finishes (at the end of the AIThread function). So the while loop merely loops forever, doing nothing, until both SimTimes are nonzero, indicating both threads have finished. Does anyone know why I could be getting such a drastic framerate decrease? [Edited by - CGameProgrammer on December 17, 2004 2:54:12 AM]
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Advertisement
Do you have any kind of synchronization ?

I'm actually surprized at your Linux result. 50% is a lot, especially for hyper threading. Are you sure the number is correct ?

Don't forget that HT is fake parallelism. You still only have a single CPU, so your two threads are going to fight for CPU/memory/IO access. Plus there is a cost in context switching threads.. especially in Windows, it seems :)

I do have a real dual core machine (dual AMD 2400). If you want i can test your program. The results should be a lot different.

Y.
Windows doesn't support multiple CPUs - you need to get a multiple CPU version of the OS (NT only IIRC and I'm not sure it even supports HT). You pay a license per physical CPU, so a dual CPU in one chip counts as one. So, in Windows, your multithreaded app was running on one CPU so it was never going to be quicker.

Skizz
Forgive me my ignorance of threading apps but I believe you have a busy loop here. The proggie will spent lots of time in that while loop, whereas it's probably not so critical to be checking those SimTime variables billions of times per second. Try adding an OS sleep call within the loop.

When you run it single threaded, you do the work of the 2 threads and nothing more, and now you have three threads. So in single threaded mode, it takes 1/17=0.0588 seconds per frame, that is 0.0588/2*3 seconds per frame for three threads that get even time. And 1/(0.0588/2*3)=11, the framerate you are getting in Windows when multithreaded..

On the other hand, this might be BS, but I'm convinced!
Quote:Original post by Skizz
Windows doesn't support multiple CPUs - you need to get a multiple CPU version of the OS (NT only IIRC and I'm not sure it even supports HT). You pay a license per physical CPU, so a dual CPU in one chip counts as one. So, in Windows, your multithreaded app was running on one CPU so it was never going to be quicker.


That's only true for a certain licence agreements with Windows Server on high-grade server machines, certainly not true for workstation editions.

NT, Win2K and XP Pro handle multiple CPUs and HT processors fine, right out of the box. XP Home, however, has been crippled and only supports one CPU (and HT is disabled).
[teamonkey] [blog] [tinyminions]
Ysaneya: I have no synchronization of any sort. Yes I'm aware of how Hyper-Threading works, and my framerate had increased by roughly 50%, though my performance in Linux was bad to begin with for some reason (partly ATI-related). Anyway, I have uploaded a new GDomin.zip. Press 'm' to toggle multithreading on or off (it's off by default). Note that you will see no difference unless you have a bunch of ships flying around, so select alot of ships and right-click somewhere on screen so they'll go there (don't forget to press Space first so you can select stuff). Let me know if it crashes; the MT conversion is not totally finished, but it should be stable. I can run the program forever and it never crashes. Also, ignore the workload statistics; they're wrong... the framerate is correct however.

Oh, I should probably mention the game will run much slower than it did with the first release; this is not due to multithreading, but due to improved collision avoidance. It's slower though, but there are still ways to speed it up.

Skizz: Windows XP Professional supports multiple CPUs; I can open the Task Manager and see the workload on each virtual CPU.

Anonymous: Interesting... very interesting. What you say makes alot of sense. I did it that weird way because I couldn't find a good way in Windows of waiting for a thread to finish; the available functions seemed weird. Linux just has a nice simple pthread_join function. Ah well.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
You can use Mutexes in Windows and WaitForSingleObject() to wait for a thread to finish.
Thanks darookie. I haven't looked at mutexes yet, but I used WaitForSingleObject (and then switched to WaitForMultipleObjects which is better for me) and I no longer get a framerate decrease when being multithreaded, so the AP was correct. But I don't get a noticeable framerate increase either.

I've now updated GDomin.zip with the 'fixed' version, Ysaneya, so I'd be interested to here your results. I probably need some sort of synchronization, though I'm not sure how that works... I get using a mutex variable to prevent conflicting writes, but no memory is written to by both threads.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Works. No crash.. but i don't see any framerate difference between ST and MT. However i do see that the CPU usage in the task manager changes a lot. Between 20 and 50% in ST, and 50 to 80% in MT.

Y.
It seems very odd that you get 50% boost in Linux. When you do two sequentical things as multithreaded, the time will be 100% + "relative time spent for switching between threads". Hyperthreading will only make the "relative time spent for switching between threads" lower -- Not negative! (At least that's how I remember hyperthreading) The multithreaded version should always be slower, but not necessarily much.

One possibility is that in Linux you have several computation-intensive threads running on background and all threads are same priority. So by doubling your own app's active thread count you will make Linux spend more time executing your app instead of other background threads. But the better solution would be to do it single-threaded and just increase that thread's priority.

This topic is closed to new replies.

Advertisement