Возня с "суперкомпьютером" и чтение документации по CUDA-вычислениям не прошли зря. Ночью со вторника на среду у меня возникла идея: а что если вынести часть нагрузки процессора не только на графическую карту, но и на другие устройства. Причем выносить не столько вычислительную нагрузку (большинство устройств много все равно не насчитает), сколько обработку более высоких уровней абстракции тех же действий, которые и должно выполнять это устройство. Например, контроллер жесткого диска будет выполнять запросы не на уровне "прочитать столько-то секторов начиная с такого-то", как сейчас, а "открыть файл с именем таким-то", при этом контроллер сам считает таблицу размещения файлов и определит, где он находится. А сетевая карточка будет не просто принимать пакеты и передавать их в память, а возьмет на себя отслеживание установленных соединений, проверку корректности доставки на уровне TCP, кеширование ARP и DNS и функции firewallа. Соответственно, контроллер клавиатуры будет не только возвращать скан-коды, но и определять символы в соответствии с текущей раскладкой.
Впрочем, при современной архитектуре компьютера прирост от этого будет незначителен, так как все по-прежнему будет упираться в шину процессор-память-устройства. Для того, чтобы от этого избавиться, нужна существенно другая архитектура компьютерной системы. На мой взгляд, она должна обладать следующими особенностями:
1. У каждого устройства имеется оперативная память, и оперативная память всех устройств логически представляет собой единое адресное пространство (для определенности будем считать, что 64-битное). (В принципе, тут ничего нового, у современных компьютеров многие устройства могут отображаться в общую память).
2. Кеш второго уровня у процессора является не ассоциативным (как сейчас), а адресуемым, и не дублирует оперативную память, а является самостоятельным запоминающим устройством с собственным диапазоном адресов. (Т.е. по сути процессор обладает собственной высокоскоростной памятью объемом несколько сотен килобайт или несколько мегабайт.)
3. Память разбита на страницы (традиционно по 4 Кб), при этом в соседних физических страницах могут находится логические страницы с совершенно разными адресами. (Тоже ничего нового, такое существует со времен 386 процессоров.)
4. Взаимодействие между устройствами возможно двумя способами: переотображение (или просто копирование) страницы памяти из одного устройства в другое (при переотображении логический адрес страницы остается неизменным) и посылка коротких сообщений (которые принимаются в специальный буфер, не входящий в логическое адресное пространство). Получение сообщения из очереди делается с помощью специальной команды процессора/микроконтроллера. Взять один байт или одно слово из страницы, отображенной в настоящий момент в другое устройство, невозможно.
5. Подгрузка необоходимых для выполнения программы страниц из оперативной памяти в память L2-кеша процессора осуществляется явной командой на переотображение страницы. (Пожалуй, это наиболее принципиальное отличие от существующей архитектуры. По сути дела, возврат к адресации вида сегмент:смещение, как это было в 16-битных системах. Впрочем, не исключаю, что для обратной совместимости будет механизм и неявной подгрузки, но он будет менее эффективным, так как в этом случае команда на подгрузку будет даваться не заранее, а в тот момент, когда потребовались данные с этой страницы, и возникнет простой до момента, когда данные будут доставлены в кеш процессора).
6. В центральном процессоре многозадачность будет полностью аппаратной, в том числе и планировщик, который умеет учитывать нахождение процессов в состоянии ожидания прихода сообщения или доставки нужной страницы. Также, возможно, будут аппаратные средста межпроцессной синхронизации. Как следствие, исчезнет такое понятие, как прерывание для процессора (хотя в промышленных компьютерах прерывания могут остаться, но обрабатываться они будут интеллектуальным контроллером, который опять же будет преобразовывать их в сообщения для процессора).
7. Обмен сообщениями между процессами, выполняющимися в центральном процессоре, также будет реализован аппаратно. И вообще обмены процесс-процесс, процесс-ядро и процесс-устройство с программной точки зрения различаться не будут вообще, если не учитывать возможные ограничения по безопасности. Сответственно, процессы, выполняющиеся на вспомогательных устройствах и на центральном процессоре должны иметь единую логическую нумерацию.
8. Программы для вспомогательных устройств могут быть как прошитыми аппаратно, так и подгружаться операционной системой по мере необходимости. Тоже ничего нового, уже сейчас существует множество устройств, для которых подгрузка прошивок осуществлятеся при загрузке системы или подключении устройства. Впрочем, думаю, по мере развития такой архитектуры от такого откажутся и прошивки будут все же аппаратными, а интерфейсы взаимодействия с устройствами сходных классов -- стандартизируются, т.е. будет примерно как во времена MS-DOS, когда OS, желая повзаимодействовать с каким-либо стандартным оборудованием, просто вызывала соответствующую функцию BIOS через программное прерывание.
9. Если расширить адресное пространство (скажем, до 80 бит, 64 бита -- адрес внутри компьютера, и 16 бит -- адрес компьютера) и возложить на сетевую карточку функции преобразования сообщений и страниц в сетевые пакеты и обратно, можно будет легко построить мощную мультикомпьютерную систему, представляющую собой нечто среднее между кластером и NUMA.
10. Наиболее сложный вопрос в такой системе -- управление памятью на логическом уровне, особенно выделение памяти в реальном времени и отслеживание того, в каком устройстве в данный момент времени находится та или иная страница.
В общем получается микроядерная OS, реализованная аппаратно (и как следствие, избавляющаяся от главной проблемы микроядерности -- больших потерь на переключение между процессами). Кроме того, под нее потребуются более интеллектуальные трансляторы, сложнее будет реализовывать обработку больших объемов данных на языках среднего и высокого уровня (в первую очередь речь идет о C с его "арифметикой указателей"), а также, возможно, интерпретируемые языки. Зато возможно повышение производительности за счет двух факторов: разгрузки системной шины (т.к. обращение устройств к памяти или друг другу будет выполняться только при переотображении страницы либо передачи сообщения, впрочем, для сообщений может быть окажется целесообразно сделать отдельную последовательную шину с очень высокой тактовой частотой) и уменьшение количества непоследовательно выполняемого кода (вместо системных вызовов, выполняемых по косвенному call, в "родных" для данной архитектуры программах будут просто стоять процессорные инструкции отправки сообщения процессу с определенным номером, а также не будет прерываний).
Интересно, увижу ли я когда-нибудь компьютер с подобной архитектурой? (И скажу при этом "вот, я еще в 2010 году говорил, что так будет!") Или же развитие вдруг пойдет иным путем... Или просто остановится, когда станет ясно, что для обычного пользователя персонального комьпютера такие мощности не нужны, а заниматься следует улучшением интерфейса в целях повышения производительности самого пользователя.