ссылки нету( Но вангую, что HT для vliw не должен сильно отличаться. Укорачиваем вдвое широкую команду, чтобы потом из двух сделать одну (инструкции в них независимы по определению), добавляем в ядро второй MMU, второй набор регистров состояния потока, флаговый регистр, ну и регистровый файл надо как-то тоже распилить надвое - и вроде как должно заработать.
так они и появляются в железе потому, что целую гору оптимизаций иначе как на уровне железа не получится сделать. Простой пример, есть 2 инструкции, одна пишет в память, другая читает. Интел видит, что операнды (=адреса памяти) у них разные, значит можно выполнить одновременно, переставить их и т.д, короче независимость инструкций для него налицо. А компилятор эльбруса видит 2 указателя, из одного читают, в другой пишут, и поди докажи, что они не равны, особенно если указатели из разных единиц трансляции, так что в одну широкую команду он не сможет их запихнуть просто так, и будет вынужден генерить дополнительный if, задействовать предикатное исполнение и тд, на что будут теряться такты, и не факт, что выигрыш будет того стоить. Или косвенный вызов - до того, как из кэша придет адрес перехода, интел смотрит в предсказатель переходов и видит, что с вероятностью 99% прыгнем туда-то, и начинает подкачивать код, исполнять его спекулятивно. Компилятор эльбруса за косвенный вызов может заглянуть только будучи JIT-ом или имея профиль выполнения (что, ну скажем, так себе), в противном случае придется подождать подкачки адреса из кэша/памяти, и только потом подкачки кода и исполнения.
Я думаю, что все, что тут тестировалось, скомпилировано под e2k, а не в режиме двоичной трансляции работает. Я читал руководство по эффективному программированию под Эльбрус (если честно, субъективно довольно красиво у них организован регистровый файл, подготовка переходов, режим спекулятивности и предикатного исполнения), и примерно представляю, что такое vliw. Комментарий о другом был. Что нужно не заставлять программистов "писать под vliw" (с ручной расстановкой префетчей, например), а процессор/компилятор допиливать, чтобы он нормально жевал современный код, с кучей мелких объектов, косвенных вызовов (привет, аппаратный предсказатель переходов!) и короткими базовыми блоками. Числодробилки, под которые Эльбрус вроде должен бы быть эффективен (но это тоже не совсем так, видел статью, где есть сравнение на программах численного моделирования, и там эльбрус тоже совсем не айс, даже в пересчете на ядро*гигагерц), сейчас пишут на GPU, и это правильно.
Эльбрусу сильно не хватает аппаратного планировщика, предсказателя переходов, и аналога HyperThreading - он, если честно, прямо просится, но я слабо себе представляю, как он может быть реализован на процессоре со статическим планированием исполнения.
При этом «Эльбрусы» работают явно медленнее из-за того, что софт написан не для VLIW, требующей совершенно другого подхода и дисциплины кода, и компиляции.
А для vliw - это как? Чтобы данные лежали ровными массивчиками, везде руками были расставлены префетчи, циклы имели статические границы и никаких вызовов функций по указателю? Век вроде 21й на дворе
когда-то работодателям было проще и дешевле покупать людей на рынке, кормить абы как и заставлять работать по куче часов в день под угрозой физической расправы.
Это ж обычная и старая проблема хранения данных во внешней памяти, только перенесенная на RAM. Построчно (= по-объектно) или поколоночно (= массивами)? Или разбивать по 10К строк и их хранить поколоночно (привет orc, parquet и иже с ними)? Колонки сильно лучше жмутся и выше локальность при доступе к колонкам, ну а если поиск нужен и рандомная вставка/удаление, и нужно какое-нибудь b-дерево? Такие же трейд-оффы и здесь, поэтому от паттерна доступа к данным и нужно отталкиваться, когда по массивам распихивать внутренности объектов, когда — сами объекты, когда по спискам/хэштаблицам/деревьям.
Алгоритм компилятор не оптимизирует. Но, надо сказать, современные компиляторы могут очень многое. Агрессивные инлайн-подстановки, раскрутка/конвейеризация циклов, аффинные преобразования на вложенных циклах, удаление мертвого кода, и тд. Не стоит забывать и о процессорных оптимизациях в виде того же branch prediction.
он сильно перегнул пальцы, угрожая деньгами. С другой стороны, понять его можно — ты платил чуваку деньги за разработку продкута, а потом видишь клон на гитхабе. Без разницы, сколько там реально конкурентов — неприятно.
У JET весьма неплохие показатели — отношение затраченной на разогрев плазмы энергии к полученной энергии составляет 0,67. Для того, чтобы получить коммерческую систему, этот коэффициент, Q, должен быть больше единицы.
Получается, что коммерческая система должна тратить энергии больше, чем получает, что бред.
Ну то, что авторы примера не умеют писать нормальный код, не говорит об инструменте плохо. Мы в 2013м году по-моему просто писали статические функции для свертки, и прописывали их вызов в файле грамматики, код смотрелся красиво и аккуратно. Про предупреждения об ошибках — вы тоже не правы, там раздел целый вроде был про это, все прекрасно можно сделать.
Если вам нравится разделять код и грамматику, то смотрите про ANTLR. Единственное — он адаптированный LL-ный, а значит, более капризный, в то время как bison — это честный LALR(1), значит он ест больше грамматик, и неоднозначные (в которых есть конфликты типа сдвиг/свертка, например) — в том числе
Есть, почитайте маны к bison-у. Там к каждому правилу грамматики можно (и по факту нужно) дописать код, который выполняет свертку физически и формирует узел AST
Начинать с грамматики лучше, явно выписать ее. Потом только парсер подбирать, лучше готовым движком воспользоваться. Раз пишете на плюсах, возьмите flex+bison, он удобен, хоть и древний.
Индекс и есть сортировка — это неверное утверждение. Есть разница в плане количества дисковых операций: сделать несколько выборок из индекса (B-дерево), или вычитать всю таблицу с диска, отсортировать (внешней сортировкой, разумеется), и потом отфильтровать.
Никак индекс не будет на C# выглядеть (если нет желания психануть и запилить свое персистентное B-дерево с блекджеком и транзакциями).
Статья называется «Как реляционная СУБД делает JOIN», и логичный, очевидный и правильный случай, когда есть индекс, почему-то не рассмотрен.
а если сделать foreign key на visits, который референсится на person, чтобы индекс создался, то может быть еще и scan по person + index search по visits, и в случае, если фильтром отсекается большая часть клиентов, то так будет эффективнее
можно на базовых блоках строить интерпретатор, тогда переход будет только в конце блока, а не в конце отдельной инструкции. Блок — это кусок байткода, оканчивающийся (по-моему, надо вспоминать) безусловным переходом
ссылки нету( Но вангую, что HT для vliw не должен сильно отличаться. Укорачиваем вдвое широкую команду, чтобы потом из двух сделать одну (инструкции в них независимы по определению), добавляем в ядро второй MMU, второй набор регистров состояния потока, флаговый регистр, ну и регистровый файл надо как-то тоже распилить надвое - и вроде как должно заработать.
это не отменяет того, что HyperThreading в эльбрусе нужен) в итаниуме, кстати, был.
так они и появляются в железе потому, что целую гору оптимизаций иначе как на уровне железа не получится сделать. Простой пример, есть 2 инструкции, одна пишет в память, другая читает. Интел видит, что операнды (=адреса памяти) у них разные, значит можно выполнить одновременно, переставить их и т.д, короче независимость инструкций для него налицо. А компилятор эльбруса видит 2 указателя, из одного читают, в другой пишут, и поди докажи, что они не равны, особенно если указатели из разных единиц трансляции, так что в одну широкую команду он не сможет их запихнуть просто так, и будет вынужден генерить дополнительный if, задействовать предикатное исполнение и тд, на что будут теряться такты, и не факт, что выигрыш будет того стоить. Или косвенный вызов - до того, как из кэша придет адрес перехода, интел смотрит в предсказатель переходов и видит, что с вероятностью 99% прыгнем туда-то, и начинает подкачивать код, исполнять его спекулятивно. Компилятор эльбруса за косвенный вызов может заглянуть только будучи JIT-ом или имея профиль выполнения (что, ну скажем, так себе), в противном случае придется подождать подкачки адреса из кэша/памяти, и только потом подкачки кода и исполнения.
Я думаю, что все, что тут тестировалось, скомпилировано под e2k, а не в режиме двоичной трансляции работает. Я читал руководство по эффективному программированию под Эльбрус (если честно, субъективно довольно красиво у них организован регистровый файл, подготовка переходов, режим спекулятивности и предикатного исполнения), и примерно представляю, что такое vliw. Комментарий о другом был. Что нужно не заставлять программистов "писать под vliw" (с ручной расстановкой префетчей, например), а процессор/компилятор допиливать, чтобы он нормально жевал современный код, с кучей мелких объектов, косвенных вызовов (привет, аппаратный предсказатель переходов!) и короткими базовыми блоками. Числодробилки, под которые Эльбрус вроде должен бы быть эффективен (но это тоже не совсем так, видел статью, где есть сравнение на программах численного моделирования, и там эльбрус тоже совсем не айс, даже в пересчете на ядро*гигагерц), сейчас пишут на GPU, и это правильно.
Эльбрусу сильно не хватает аппаратного планировщика, предсказателя переходов, и аналога HyperThreading - он, если честно, прямо просится, но я слабо себе представляю, как он может быть реализован на процессоре со статическим планированием исполнения.
А для vliw - это как? Чтобы данные лежали ровными массивчиками, везде руками были расставлены префетчи, циклы имели статические границы и никаких вызовов функций по указателю? Век вроде 21й на дворе
Del
Алгоритм компилятор не оптимизирует. Но, надо сказать, современные компиляторы могут очень многое. Агрессивные инлайн-подстановки, раскрутка/конвейеризация циклов, аффинные преобразования на вложенных циклах, удаление мертвого кода, и тд. Не стоит забывать и о процессорных оптимизациях в виде того же branch prediction.
Получается, что коммерческая система должна тратить энергии больше, чем получает, что бред.
Если вам нравится разделять код и грамматику, то смотрите про ANTLR. Единственное — он адаптированный LL-ный, а значит, более капризный, в то время как bison — это честный LALR(1), значит он ест больше грамматик, и неоднозначные (в которых есть конфликты типа сдвиг/свертка, например) — в том числе
Можно страуструпа перечитать, и Майерса (в плюсах это мастхэв, у него и по современным фичам есть книги)
Начинать с грамматики лучше, явно выписать ее. Потом только парсер подбирать, лучше готовым движком воспользоваться. Раз пишете на плюсах, возьмите flex+bison, он удобен, хоть и древний.
Статья называется «Как реляционная СУБД делает JOIN», и логичный, очевидный и правильный случай, когда есть индекс, почему-то не рассмотрен.