Хороший вопрос или хотя бы один с интересным ответом. Часть этого ответа отображает мир, в котором процессоры могут эффективно масштабироваться по ширине, а не с несколькими отдельными ядрами. Лицензирование / цена модели будут другими!
Остальное объясняет, почему они не могут. Резюме:
- Стоимость нескольких ядер масштабируется близко к линейному
- Затраты на расширение суперскалярного конвейера 1 ядра масштабируются ~ квадратично. Это выполнимо при достаточно грубой силе, в любом случае, до некоторой точки. Однопоточная производительность очень важна для интерактивного использования (важна сквозная задержка, а не только пропускная способность), поэтому современные высокопроизводительные высокопроизводительные центральные процессоры платят эту цену. например, Skylake (4 в ширину), Ryzen (5 или 6 в ширину) и Apple A12 (7 в ширину для больших ядер, 3 в ширину для небольших энергоэффективных ядер)
- Серьезное снижение IPC возвращается от простого расширения конвейера за пределы 3 или 4 в ширину, даже с неупорядоченным выполнением, чтобы найти ILP . Пропуски веток и кешей трудны, и все равно останавливают весь конвейер.
Вы не упомянули частоту, просто IPC, но масштабирование тоже сложно. Более высокая частота требует более высокого напряжения, поэтому мощность зависит^1
от частоты в кубе : непосредственно от частоты и ^2
от напряжения. (Конденсатор хранит энергию в масштабе V ^ 2, и большая часть динамической мощности за пределами тока утечки поступает от накачки заряда в емкостную нагрузку затворов + проводов FET.)
Производительность = частота умножения IPC. (В рамках той же архитектуры. Более широкая SIMD позволяет выполнять ту же работу с меньшим количеством инструкций, а некоторые ISA более плотные, чем другие, например, MIPS часто требует больше инструкций для выполнения той же работы, чем x86 или AArch64.)
Затраты указаны в площади кристалла (стоимость изготовления) и / или мощности (что косвенно ограничивает частоту, поскольку охлаждение затруднено). Кроме того, снижение мощности и производительности на ватт является самоцелью, особенно для мобильных устройств (батареи) и серверов (плотность мощности / затраты на охлаждение / затраты на электроэнергию).
До того, как было задействовано многоядерное соединение на сокет, у вас были системы с несколькими сокетами для высокопроизводительных сценариев использования, где вы хотели увеличить пропускную способность, чем это было возможно с одним процессором, который мог быть изготовлен, так что это были единственные системы SMP. (Серверы, рабочие станции высокого класса).
Если бы одно ядро могло масштабироваться так эффективно, как вы хотели, у нас были бы системы с 1 физическим ядром на сокет и SMT (например, HyperThreading), чтобы они могли работать как несколько логических ядер. Типичные настольные компьютеры / ноутбуки имеют только одно физическое ядро, и мы не будем пытаться распараллелить вещи, которые не масштабируются линейно, с большим количеством ядер. например, make -j4
чтобы использовать преимущества серверов с несколькими сокетами и / или скрыть задержку ввода-вывода на рабочем столе. (Или, может быть, мы все же попытались бы распараллелить много, если бы ширина конвейера легко масштабировалась, а IPC - нет, поэтому нам пришлось использовать больше потоков SMT.) Ядро вашей ОС все равно должно было бы работать на всех логических ядрах, если только не процессор Представления SMT для ОС сильно отличались, поэтому параллельные алгоритмы планирования и блокировки все равно были бы там необходимы.
Дональд Кнут сказал в интервью 2008 года
С таким же успехом я мог бы вспомнить о моем личном недовольстве нынешней тенденцией к многоядерной архитектуре. Для меня это выглядит более или менее так, как будто разработчики аппаратного обеспечения исчерпали свои идеи, и что они пытаются переложить вину за будущую кончину закона Мура на разработчиков программного обеспечения , предоставив нам машины, которые работают быстрее только на нескольких ключевые ориентиры!
Да, если бы у нас были чудесные одноядерные процессоры с 8-кратной пропускной способностью в реальных программах , мы, вероятно, все равно использовали бы их. С системами с двумя сокетами, только когда стоило платить гораздо больше за большую пропускную способность (не однопоточную производительность).
Несколько процессоров сокращают затраты на переключение контекста, когда работают несколько программ (позволяя им действительно работать параллельно вместо быстрого переключения между ними); упреждающая многозадачность, прерывающая работу огромного вышедшего из строя механизма, который потребует процессор, вероятно, повредит даже больше, чем сейчас.
Физически это будет одно ядро (для простой иерархии кеша без межсоединений между ядрами), но поддерживающее SMT (например, Intel HyperThreading), чтобы программное обеспечение могло использовать его как 8 логических ядер, которые динамически конкурируют за пропускную способность. Или когда только 1 поток запущен / не остановлен, он получит полную выгоду.
Таким образом, вы использовали бы несколько потоков, когда это было на самом деле проще / естественнее (например, отдельные процессы выполнялись одновременно), или для легко распараллеливающихся проблем с цепочками зависимостей, которые не позволили бы максимизировать IPC этого зверя.
Но, к сожалению, со стороны Кнута хочется думать, что многоядерные процессоры на этом этапе перестают быть чем-то особенным.
Однопоточное масштабирование производительности
Я думаю, что если бы они сделали 1-ядерный эквивалент 8-ядерного процессора, то это одно ядро увеличило бы IPC на 800%, чтобы вы могли получить полную производительность во всех программах, а не только в тех, которые оптимизированы для нескольких ядер.
Да, это правда. Если бы было возможно построить такой процессор вообще, это было бы очень удивительно. Но я думаю, что это буквально невозможно в том же процессе производства полупроводников (то есть, такое же качество / эффективность транзисторов). Это, конечно, невозможно при том же энергопотреблении и площади кристалла, что и у 8-ядерных процессоров, даже если вы сэкономите на логике для склеивания ядер и не потребует столько места для частных кэшей на ядро.
Даже если вы допустите увеличение частоты (поскольку реальный критерий - это работа в секунду, а не работа в такт), увеличение производительности даже в 2 раза быстрее будет огромной проблемой.
Если бы это было возможно в любом месте рядом с той же силой и бюджет штампом площади ( при этом производственные затраты) , чтобы построить такой процессор, да производители CPU уже будут строить их таким образом.
В частности, больше ядер или более широких ядер? раздел, для необходимого фона, чтобы понять этот ответ; все начинается с того, как работают конвейерные процессоры по порядку, а затем суперскалярно (несколько инструкций за такт). Затем объясняется, как мы достигли мощной стены прямо в эпоху P4, что привело к концу легкого масштабирования частоты, оставив в основном только IPC и выполнив больше работы по каждой инструкции (например, SIMD) в качестве пути продвижения вперед, даже с небольшими транзисторами.
Увеличение ширины конвейера (макс. Инструкций за такт) обычно масштабируется по ширине . Эта стоимость измеряется в области и / или мощности кристалла для более широкой параллельной проверки зависимостей (обнаружения опасности) и более широкого планировщика с нарушением порядка, чтобы найти готовые инструкции для выполнения. И больше портов для чтения / записи в вашем регистровом файле и кеше, если вы хотите запускать инструкции, отличные от nop
. Особенно, если у вас есть 3-х входные инструкции, такие как FMA или add-with-carry (2 регистра + флаги).
Также уменьшается отдача IPC для расширения процессоров ; большинство рабочих нагрузок имеют ограниченный ILP (параллелизм на уровне команд) для использования процессорами, поэтому расширение ядра не увеличивает IPC (количество команд за такт), если IPC уже ограничен шириной меньше ядро по цепочкам зависимостей, пропаданиям веток, пропаданиям кэша или другим остановкам. Конечно, вы получите ускорение в некоторых развернутых циклах с независимыми итерациями, но это не то, на что большинство кода тратит большую часть своего времени. Команды сравнения / ветвления составляют 20% от совокупности команд в «типичном» коде IIRC. (Я думаю, что я прочитал числа от 15 до 25% для различных наборов данных.)
Кроме того, потеря кэша, которая останавливает все зависимые инструкции (а затем и все, когда емкость ROB достигнут) стоит дороже для более широкого ЦП. (Возможные издержки, связанные с отсутствием большего количества исполнительных блоков; больше потенциальной работы не выполняется.) Или пропуск ветки аналогичным образом вызывает пузырь.
Чтобы получить 8-кратный IPC, нам нужно как минимум 8-кратное улучшение точности предсказания ветвлений и частоты обращений к кешу . Но частота попаданий в кэш плохо масштабируется, когда объем кеша превышает определенный уровень для большинства рабочих нагрузок. И предварительная загрузка HW умна, но не может быть такой умной. И при 8-кратном IPC предикторам ветвлений необходимо производить в 8 раз больше прогнозов за цикл, а также делать их более точными.
Текущие методы построения процессоров исполнения не по порядку могут находить ILP только на коротких дистанциях . Например, размер ROB в Skylake равен 224 мопам в слитых доменах, а планировщик для неисполненных мопов - в 97 неиспользуемых доменах. См. Понимание влияния lfence на цикл с двумя длинными цепочками зависимостей, для увеличения длины для случая, когда размер планировщика является ограничивающим фактором при извлечении ILP из 2 длинных цепочек инструкций, если они становятся слишком длинными. И / или увидеть этот более общий и вводный ответ ).
Таким образом, поиск ILP между двумя отдельными длинными циклами - это не то, что мы можем сделать с помощью оборудования. В некоторых случаях возможна динамическая бинарная перекомпиляция для объединения циклов, но сложная и не очень полезная для процессоров, если они не пойдут по пути Transmeta Crusoe. (слой эмуляции x86 поверх другого внутреннего ISA; в этом случае VLIW). Но стандартные современные конструкции x86 с кэшем UOP и мощными декодерами нелегко превзойти для большинства кода.
А вне x86 все ISA, которые все еще используются, относительно легко декодируются, поэтому нет никакой мотивации для динамической перекомпиляции, кроме как для оптимизации на большие расстояния. TL: DR: надежда на магические компиляторы, которые могут предоставить больше ILP аппаратному обеспечению, не сработала для Itanium IA-64 , и вряд ли будет работать для сверхширокого ЦП для любой существующей ISA с последовательной моделью исполнения.
Если бы у вас был сверхширокий ЦП, вы бы определенно хотели, чтобы он поддерживал SMT, чтобы вы могли постоянно загружать его работой, запустив несколько потоков с низким ILP.
Поскольку Skylake в настоящее время имеет ширину 4 мопа (и обеспечивает реальный IPC от 2 до 3 мопов за такт, или даже ближе к 4 в высокопроизводительном коде), гипотетический 8-кратный ЦП будет иметь ширину 32!
Быть способным разделить это обратно на 8 или 16 логических ЦП, которые динамически распределяют эти ресурсы выполнения, было бы фантастическим: не остановленные потоки получают всю полосу пропускания внешнего интерфейса и пропускную способность бэкэнда.
Но с 8 отдельными ядрами, когда поток останавливается, нет ничего другого, чтобы поддерживать загруженные исполнительные блоки; другие темы не приносят пользы.
Выполнение часто прерывистое: оно останавливается в ожидании загрузки кэша, а затем, когда это происходит, многие параллельные инструкции могут использовать этот результат. С супершироким процессором этот всплеск может идти быстрее, и он действительно может помочь с SMT.
Но у нас не может быть волшебных сверхшироких процессоров
Таким образом, чтобы получить пропускную способность, мы вместо этого должны выставлять параллелизм аппаратным средствам в форме параллелизма на уровне потоков . Обычно компиляторы не очень хорошо знают, когда и как использовать потоки, за исключением простых случаев, таких как очень большие циклы. (OpenMP или gcc -ftree-parallelize-loops
). Человеческий ум все еще требует переделки кода, чтобы эффективно выполнять полезную работу параллельно, потому что межпотоковое взаимодействие обходится дорого, как и запуск потоков.
TLP - это грубый параллелизм, в отличие от мелкозернистого ILP в пределах одного потока выполнения, который HW может использовать.
Процессоры, предназначенные для интерактивных рабочих нагрузок (такие как Intel / AMD x86 и высокопроизводительные ядра Apple / ARM AArch64), безусловно, способствуют снижению отдачи от масштабирования IPC, поскольку однопоточная производительность по-прежнему так важна, когда задержка имеет значение, а не только пропускная способность для массово параллельные проблемы.
Возможность одновременного запуска 8 копий игры со скоростью 15 кадров в секунду гораздо менее ценна, чем возможность запускать одну копию со скоростью 45 кадров в секунду. Производители процессоров знают об этом, и поэтому современные процессоры используют неупорядоченное выполнение, даже если это требует значительной мощности и площади. (Но графические процессоры этого не делают, потому что их рабочая нагрузка уже в основном параллельна).
Многоядерное аппаратное обеспечение Intel Xeon Phi (Knight's Landing / Knight's Mill) представляет собой интересный промежуточный пункт: очень ограниченное выполнение по порядку и SMT, чтобы ядра 2-ширины обеспечивались SIMD-инструкциями AVX512 для сокращения чисел. Ядра основаны на архитектуре Intel Silvermont с низким энергопотреблением. (Exec-out exec, но с небольшим окном переупорядочения, намного меньшим, чем у крупного семейства Sandybridge. И более узкий конвейер.)
Кстати, все это ортогонально SIMD. Выполнение большей работы по каждой инструкции всегда помогает, если это возможно для вашей проблемы.
Модели ценообразования
Модели ценообразования программного обеспечения основаны на текущем аппаратном обеспечении.
Модели с многоядерным лицензированием стали более распространенными (и применимыми даже к настольным ПК с одним сокетом) с появлением многоядерных процессоров. До этого это было актуально только для серверов и больших рабочих станций.
Если бы программному обеспечению не требовалось многоядерных процессоров для работы на максимальной скорости, на самом деле не было бы способа продавать его дешевле людям, которые не получают от него такой большой выгоды, потому что работают на более слабом процессоре. Если, возможно, программно-аппаратная экосистема не разработала элементы управления на «каналах SMT», которые позволяют настроить максимальную ширину выполнения для кода, выполняемого на этом логическом ядре. (Снова представьте мир, в котором процессоры масштабируются по ширине конвейера вместо нескольких отдельных ядер.)