Я не пытаюсь ослабить ваш энтузиазм, но это уже вполне понятная проблема. Я постараюсь объяснить, чего ожидать ниже. Но, возможно, было бы лучше сделать ваш проект в другой области. Как насчет «Максимизации пропускной способности хеширования MD5», тогда вы не ограничитесь только просмотром потоков.
Я думаю, что когда вы пишете свой проект, вам нужно будет предложить какой-то анализ того, когда параллельная обработка уместна, а когда нет.
Каждый раз, когда ваш ЦП переключается на другой поток, он должен сохранять текущий контекст потока и загружать новый контекст потока. Эти издержки не возникают в однопоточном процессе (за исключением управляемых служб, таких как сборка мусора). Таким образом, при прочих равных условиях добавление потоков не повысит производительность, поскольку должно выполнять исходную рабочую нагрузку и все переключение контекста.
Но если в вашем распоряжении несколько процессоров (ядер), создание одного потока на процессор будет означать, что вы сможете распараллелить вычисления без затрат на переключение контекста. Если у вас больше потоков, чем процессоров, переключение контекста станет проблемой.
Существует 2 класса вычислений: IO-привязанный и вычисляемый. Вычисления, связанные с вводом-выводом, могут потратить большое количество циклов ЦП в ожидании ответа от некоторого оборудования, такого как сетевая карта или жесткий диск. Из-за этих издержек вы можете увеличить количество потоков до точки, где ЦП снова будет максимально увеличен, и это может отменить стоимость переключения контекста. Однако существует ограничение на количество потоков, после которого переключение контекста займет больше времени, чем потоки блокируют для ввода-вывода.
Вычисления с привязкой к вычислениям просто требуют времени ЦП для обработки чисел. Это вид вычислений, используемый взломщиком паролей. Операции с привязкой к вычислениям не блокируются, поэтому добавление большего количества потоков, чем процессоров, приведет к снижению общей пропускной способности.
C # ThreadPool уже позаботился обо всем этом за вас - вы просто добавляете задачи и ставите их в очередь, пока не станет доступен поток. Новые потоки создаются только тогда, когда поток заблокирован. Таким образом, переключение контекста сводится к минимуму.
У меня есть четырехъядерный компьютер - разбить проблему на 4 потока, каждый из которых выполняется на собственном ядре, будет более или менее быстро, так как моя машина может перебирать пароли.
Чтобы серьезно распараллелить эту проблему, вам понадобится много процессоров. Я читал о , использующем графический процессор для решения этой проблемы.
Есть анализ векторов атак, которые я записал здесь , если он вам нужен. Радужные таблицы и компромиссы между процессором и памятью были бы еще одной интересной областью для реализации проекта.