Hyperthreading (running two threads in one physical core) works by letting the second thread use parts of the core which aren't being used by the first thread. But the thing is, if a computing task is CPU-bound, it's usually because a specific part of the cores (say, the floating point arithmetic unit) is being fully used. The second thread won't be able to use that part of the core because the first thread is already using it, so there's little to no benefit to running a second thread on the core.
So for hyperthreading to be effective requires a very diversified task set where different threads need different parts of the CPU simultaneously. In terms of common real-life tasks, this happens most often in video encoding/rendering...