при весьма хитром условии: каждый поток не загружает ни один из портов запуска на 90%-100% на значительное время
можно ли считать, что если программа в однопоточном варианте загружает одно ядро на 100%, то и в многопоточном варианте она загрузит 4 ядра на все 100% и, следовательно, мне нужно ориентироваться на 4 ядра?
Можно, при одном важном условии: загрузку определяете не по диспетчеру задач! Я ведь говорил не о загрузке всего процессора (что с некоторыми важными оговорками и показывает диспетчер задач), а о загрузке любого из портов запуска в процессоре. Например если абстрактный процессор содержит лишь один порт запуска плавающих инструкций, а вся программа практически только из них и состоит, то следствие будет выполняться, даже если другие 5 портов запуска (для других инструкций) простаивают. А если портов запуска вычислительных инструкций 4, причём не одинаковых, и все они не загружаются на 90%-100%, то нет, распареллеливание на два потока уменьшит время прогона даже на одном ядре (в винде можно заставить программу исполняться лишь на выделенных ядрах).
Во всех этих случаях диспетчер задач покажет 100% загрузку ядра процессора, хотя много внутренних блоков могут вовсе простаивать.
Но вообще всё равно возможны исключения и другие зависимости, тут очень много деталей и тонкостей, которые могут стать важными именно в многопоточной работе. Один из известных примеров, он есть в той заметке по ссылке выше, запись разными ядрами в одну строку кэша в памяти. Не чтение, а именно запись. С записями в память вообще надо очень аккуратно. Или например будет излишняя конкуренция между ядрами за кэш L3, которого хватало на один поток, но станет мало на все ядра. Ну про стоимость синхронизации и взаимные блокировки говорить не буду, это везде освещено.
Короче всё сложно. Если кто даст хорошее руководство (на русском) - и сам почитаю.