About hardware multithreading
It may be helpful to show the motivation for this kind of parallelism. 

Compared to other components (such as memory access), computation, especially adding/subtraction, is cheap on chips. It takes very little space, relatively, to add another adder - and of course that adder could be used for address calculations as well as for actual arithmetic. 

So more ALUs are easy to add. The problem is how to keep them busy. For instance, if you are calculating A+B+C then you need to work out A+B first and then add C to it. Nothing useful can be done with C until you have worked out A+B. So two ALUs don’t help and one is idle. 

There is a lot that a CPU can do in terms of sorting out what calculation depends on what data. If a compiler emits code for “add A to B, store in X, add C to D, store in Y, add X to Y” then the chip itself can work out that the first two adds are independent of each other so can be executed simultaneously by two ALUs (but that the third add depends on the results of the first two).

But in many instruction streams there isn’t enough scope for such parallelism, because of the problem of having to wait for results. This is particularly annoying when memory access is involved because memory today is hundreds of times slower than it was in the 1980s, so there are long periods when everything may be idle waiting for memory data to arrive. 

The hyper-threading solution is to run two unrelated instruction streams on the same core at the same time. Since they are unrelated, the data for one never depend on a result from the other, and while one is waiting for memory there is a good chance that the other will not be. The main cost is a doubling of the number of registers (one set of registers per instruction stream) but that is silicon area, not long-distance wiring, so it is cheap. 

The threads in a core still share the same memory access mechanism, including the cache, so how well all this works does depend on what the instruction streams are doing. If they are both memory-intensive then they will get in each other’s way. 

The term “multithreading” is incorrect for this kind of setup because multithreading means any way of accomplishing a goal by means of multiple threads, irrespective of the actual bits of hardware that execute the threads.