So I've got this program I made, and I wanted to speed it up, using multithreading, to make use of my quad core. The program itself fully supports multithreading. The problem is, that when I'm running the program, using just one; CreateThread() it finishes in 6seconds, if I run 2 it finishes in about 12, and with the same result, why would single threading be faster? - The timer is started after the thread creation, so it isn't the extra overhead!

Please help me out, my brain is hurting >.<

Could it be the Windows API threads?

Dani AI

Generated

Short version: Windows threads are fine — the behavior you describe almost always means the work is being serialized or suffering severe contention, not that CreateThread itself is mysteriously slow. is right that thread overhead exists, and is right that if the work is inherently serial you won't get a speedup. The surprising part here is the two-thread run taking twice as long; that points to locks, I/O or cache contention that force the threads to effectively run one after the other (or thrash the caches).

Things to check (most common causes and fixes)

  • Large critical sections or a mutex around the “real work” — search for any global lock and remove or reduce it. Partition data so each thread works independently and combine results at the end.
  • Console or file I/O from worker threads — I/O is often serialized by the runtime. Buffer per-thread output and write once.
  • Heap/allocator contention — heavy malloc/free from many threads can serialize on internal locks; try a per-thread pool or a scalable allocator.
  • False sharing — independent per-thread counters or structs located on the same cache line cause massive coherence traffic. Align/pad per-thread data to cache-line size (typically 64 bytes) or use alignas(64) / padding. See False sharing.
  • Debug build, iterator-debugging or sanitizers — test in a release build with optimizations.
  • If you use the CRT, prefer _beginthreadex over CreateThread for CRT thread-local initialization (see Microsoft docs).

How to isolate the problem

  • Run a simple synthetic CPU-only test (no locks, no I/O) in Release. If two workers finish in roughly half the time, your environment is OK.
  • Watch per-core CPU in Task Manager / Process Explorer to see if multiple cores are actually busy.
  • Use a profiler / ETW / Visual Studio Concurrency Visualizer to find time spent in waits/locks.
  • If you find locking, change to per-thread buffers or atomics, or reduce critical region scope.

Amdahl’s law explains why small serial parts can kill scaling; check that first: Amdahl’s law.

Quick test to try (Release build): run two independent CPU-bound threads doing pure computation (no I/O, no shared data) and compare timings. If that scales, the bug is in shared state or runtime calls.

Recommended Answers

All 3 Replies

Thread management takes cpu cycles...

Thread management takes cpu cycles...

True, but equal to 3CPU cores out of 4?

Multi-threading really works only if your process is going to be waiting on certain conditions. If your process locks up the CPU for 5 minutes, then running 2 processes will lock it up for 10 minutes. But if your process has some idle time somewhere, then you could get a gain.

Multi-threading is really used to support simultaneous processes, such as a web server etc and not really to speed up a process -at least on a single computer. If you want to use 2 computers with two seperate chips and buses, then that's a different story.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.