Ответ 1
Multi-CPU была первой версией: у вас будет одна или несколько материнских плат с одним или несколькими чипами ЦП на них. Основная проблема здесь заключалась в том, что процессоры должны были бы выставить некоторые из своих внутренних данных на другой процессор, чтобы они не мешали им.
Следующий шаг - гиперпоточность. Один чип на материнской плате, но он имел некоторые части дважды внутри, поэтому он мог выполнять две инструкции одновременно.
Текущая разработка является многоядерной. Это в основном оригинальная идея (несколько полных процессоров), но в одном чипе. Преимущество: дизайнеры чипов могут легко поместить дополнительные проводы для сигналов синхронизации в чип (вместо того, чтобы маршрутизировать их на штырь, затем поверх переполненной материнской платы и во второй чип).
Сегодня суперкомпьютеры многопроцессорны, многоядерные: у них много материнских плат с обычно 2-4 процессорами на них, каждый процессор многоядерный и каждый имеет свою собственную RAM.
[РЕДАКТИРОВАТЬ] У тебя это очень хорошо. Всего несколько мелких пунктов:
-
Hyper-threading отслеживает два контекста сразу в одном ядре, выставляя больше parallelism для ядра процессора вне очереди. Это приводит к тому, что исполнительные блоки питаются от работы, даже когда один поток застопоривается на пропуске кеша, неверно передает ответ или ожидает результатов от команд с высокой задержкой. Это способ получить более полную пропускную способность, не реплицируя много аппаратного обеспечения, но, если угодно, это замедляет каждый поток по отдельности. Подробнее см. в этом Q & A и объяснение того, что было не так с предыдущей формулировкой этого параграфа.
-
Основная проблема с многопроцессорным процессором заключается в том, что запущенный на них код, в конечном итоге, получит доступ к ОЗУ. Есть N процессоров, но только одна шина для доступа к ОЗУ. Таким образом, у вас должно быть какое-то оборудование, которое гарантирует, что: a) каждый процессор получает достаточный объем доступа к ОЗУ, b) тот доступ к той же части ОЗУ не вызывает проблем и c) самое главное, что CPU 2 будет уведомлен когда ЦП 1 записывает на некоторый адрес памяти, который имеет ЦП 2 во внутреннем кеше. Если этого не произойдет, CPU 2 с радостью будет использовать кешированное значение, не обращая внимания на то, что он устарел
Представьте, что у вас есть задачи в списке, и вы хотите распространять их на все доступные процессоры. Таким образом, CPU 1 будет извлекать первый элемент из списка и обновлять указатели. CPU 2 сделает то же самое. По соображениям эффективности оба процессора будут не только скопировать несколько байтов в кеш, но и всю "линию кэша" (что бы это ни было). Предполагается, что когда вы читаете байт X, вы тоже скоро увидите X + 1.
Теперь оба процессора имеют копию памяти в кеше. Затем CPU 1 извлекает следующий элемент из списка. Без синхронизации кеша он не заметил, что CPU 2 также изменил список, и он начнет работать с тем же элементом, что и CPU 2.
Это то, что эффективно делает многопроцессор настолько сложным. Побочные эффекты этого могут привести к производительности, которая хуже того, что вы получите, если весь код работает только на одном процессоре. Решение было многоядерным: вы можете легко добавить столько проводов, сколько необходимо для синхронизации кешей; вы даже можете копировать данные из одного кеша в другой (обновлять части строки кэша без необходимости их очистки и перезагрузки) и т.д. Или логика кэша может гарантировать, что все процессоры получат одну и ту же линию кэша, когда они обращаются к той же части реальной ОЗУ, просто блокируя CPU 2 на несколько наносекунд, пока CPU 1 не внесет свои изменения.
[EDIT2] Основная причина, по которой многоядерность проще, чем multi-cpu, заключается в том, что на материнской плате вы просто не можете запускать все провода между двумя микросхемами, которые вам нужны для эффективной синхронизации. Плюс сигнал распространяется только на вершины 30 см/нс (скорость света, в проводе у вас, как правило, гораздо меньше). И не забывайте, что на многослойной материнской плате сигналы начинают влиять друг на друга (перекрестные помехи). Нам нравится думать, что 0 - 0 В, а 1 - 5 В, но на самом деле "0" - это что-то между -0,5 В (овердрайв при отбрасывании линии от 1- > 0) и .5В, а "1" - что-то выше 0,8 В.
Если у вас есть все внутри одного чипа, сигналы работают намного быстрее, и у вас может быть столько, сколько вам нравится (ну, почти:). Кроме того, перекрестные помехи намного легче контролировать.