HailMary, thanks for that excellent explanation! I guess this means that current generation processors still push all the registers for a thread context shift. Too bad. I don't know how much really could be saved by optimizing this, I recall that a few thousand instructions generally get executed before the thread swap. The gate call was equivalent to about a dozen regular instructions, it took really long on the 486. If there were hidden sets of registers then this would be more on the order of perhaps two regular instructions, until you ran out of hidden register sets. Just offset into the descriptor table and load a new register frame.
I recall processor designs which used register frames in main memory, but that obviously is too slow for current processors. Even if it is put in L1 cache it would unacceptably slow down register accesses. It would have to be in the core itself, so the number of sets would be limited. Looking at the Windows task manager, I see that I currently have 390 threads, so it would take a lot of space in the core to make this efficient on a server (which can have many more threads).