Windows распределяет потоки Python по ядрам?
Начнёт, но работать в один момент времени будет только одно ядро. Утилизация процессоров в Python решается запуском отдельного процесса на каждое ядро, а внутри процесса лучше использовать асинхронность, а не многопоточность.
Запуск тредов в количестве, которое превышает количество ядер - это путь к драматическому росту latency и падению скорости.

Что в Windows (IO Completion Ports), что в Linux (epoll), все самые свежие механизмы обслуживания массовых TCP подключений запускают ровно столько тредов, сколько есть ядер, и спулят между ними события из сокетов. Именно поэтому перед разного рода скриптульками на Питоне ставят Большого Железного Феликса (nginx), который будет оптимально запихивать IO в нужные задачи.

Без этого будут происходить многократные дерганья контекстов и сбросы кэшей на процессоре, причем не тогда, когда это имеет смысл (операция IO завершилась, кэш не нужен), а когда попало.