Category: компьютеры

Category was added automatically. Read all entries about "компьютеры".

with Cat The Cat

Сайт модульбанка

Если кто не знает, но основным достижением айфона была возможность работать (худо-бедно, но!) с обычными сайтами, а не с ухудшенными специальными мобильными версиями.

Это 2008 год. Вы работаете с 2014 года.

Иметь специальную ущербную версию сайта для мобильников в 2017 это не сервис, а ровно наоборот. Опыт взаимодействия с банком с компьютера и через приложение не переносится - наличие приложения, которое не копирует ваш обычный сайт это трата ваших денег и времени клиентов.

Если вам, руководители модульбанка, сказали, что такая версия нужна, то вас обманули и вытянули деньги ни за что. Если вы сами так решили, это прискорбно. В любом случае, получилось плохо и вы выглядите некомпетентно.

Это я к чему - где в мобильной версии вашего сайта вход в интернет-банк?
with Cat The Cat

Легион и Кальвин

http://legion.stanford.edu и https://github.com/yaledb/calvin

Заметная часть сложности Легиона состоит в необходимости принимать решения о том, что (задачи и используемые ими куски памяти) и куда (процессоры и память) должно идти. Эти решения принимаются в распределённом режиме работы и в обязательном порядке подвержены всем прелестям такого режима. Например, простое решение о том, на какой процессор поместить задачу представлят собой (внутри) продолжение, написанное на шаблонах C++.

Задачи в Легионе очень похожи на транзакции - в задачу приходят подготовленные данные, задача что-то читает и что-то пишет, всё это указано в заголовке задачи. Как и транзакции, задачи в Легионе должны давать одинаковый результат при одинаковых входных данных. В общем, можно приравнять транзакции и задачи.

Чем тут интересен опыт Кальвина? Кальвин выполняет отдельный этап упорядочения транзакций. Он сортирует их по зависимостям и выполняет в вычисленном порядке, с дублированием, логом и прочими полезными вещами. Сортировка выполняется распределённо, с использованием Paxos (кстати, его реализация в Кальвине очень смешная). Так же и там же может происходить и оптимизация.

И если в случае нынешнего состояния дел Легиона определение критического пути приложения оставлено на откуп пользователя ("сделай custom mapper"), то в случае Кальвина это может быть выполнено автоматически, декларативно.

На этом у меня, пока, всё.
with Cat The Cat

Вспомнил про свою идею.

http://thesz.livejournal.com/1448306.html

Если в векторный вычислитель запихнуть поддержку операций стековой машины, то можно гонять одновременно несколько десятков стековых машин. Со всеми прелестями наподобие внеочередного выполнения, группировки запросов к памяти и так далее.

Надо обдумать.

Пока видимый минус - возможная просадка быстродействия из-за конвейера к вычислителю. Но и это тоже обходится.
with Cat The Cat

Надо отметить, что был неправ.

http://science.energy.gov/~/media/ascr/pdf/program-documents/docs/Arch_tech_grand_challenges_report.pdf

Похоже, существуют определенные физические ограничения на интерфейс с памятью, которые не дают сделать баланс лучше, чем 1/5 (как у Эльбруса) даже гигантам типа Интела.

У Xeon Phi баланс примерно 1/5 и сходная тактовая частота, у NVidia Tesla - 1/10 и даже меньше, при этом тактовая частота даже меньше Эльбрусовской.

"Был неправ. Вспылил. Прошу разрешения загладить, искупить."
with Cat The Cat

Теперь не просто про VLIW вообще, а про новый планируемый Эльбрус конкретно.

Вот ссылка, которой со мной поделились в предыдущем посте: http://alexanius-blog.blogspot.ru/2014/11/8.html

Готовится новый Эльбрус, со скоростью в 1,2ГГц и пиковой производительностью в 250ГФЛОПС на числах одинарной точности.

Долго распространяться не буду, вот главное: на 250ГФЛОПС пропускной способности памяти 51Гбайт/с.

Вот другая ссылка: http://www.scientificcomputing.com/articles/2007/01/hpc-balance-and-common-sense

На один ФЛОПС производительности необходимо иметь один байт в секунду пропускной способности. Не менее одного байта, если быть точным. Два первых камня Эльбруса имели пропускной способности с запасом, примерно полтора байта на ФЛОПС.

Поэтому новый Эльбрус будет стоять. Даже не так. Он будет СТОЯТЬ!!! Как ни один VLIW не стоял до этого.

Про кадровые решения, которые должны воспоследовать, я умолчу.
with Cat The Cat

Почему VLIW это плохо.

Надо просуммировать, ибо считать Эльбрус 2СМ хорошим процессором в смысле качества архитектуры я смысла не вижу.

VLIW, Very Large Instruction Word, выдает несколько RISC-подобных команд за один такт. Команды эти двух-трёх операндные, наподобие команд MIPS. Команды группируются в длинное слово разными способами, ни один из которых не является хорошим.

Выдача длинного слова на выполнение не производится до тех пор, пока аргументы ВСЕХ команд длинного слова не готовы. То есть, если одна команда использует результат команды деления (с переменным числом тактов, для наглядности), то все команды длинного слова будут стоять в ожидании.

Источников непредсказуемой задержки у нас не так уж и много - это деление и обращение к памяти. Обращение к памяти в некоторых случаях может быть предсказано, таких случаев не много. В основном, это простая линейная алгебра и простая обработка сигналов. Все остальные задачи будут требовать устойчивости к задержкам обращения в память.

Практически все VLIW процессоры плохо работают на обычном коде, представленном в SPECint.

В обзоре Эльбруса он отставал на 7Zip от Intel Core i7 в семь раз, примерно. Отличие тактовых частот было почти 12 раз. Если бы мы замедлили Intel Core i7 до тактовой частоты Эльбруса, то его конвейер сократился бы до 5 шагов (с 20) и скорость выполнения увеличилась бы вчетверо, если не больше. А это означает, что на тактовой частоте Эльбруса гипотетический медленный i7 с длинным конвейером работал бы примерно в полтора раза медленней, а с укороченным - примерно втрое быстрее.

Команды в VLIW группируются либо по числу устройств (и дополняются NOOP до нужного числа), либо присутствует специальный бит остановки. Оба способа плохи с точки зрения двоичной совместимости. Если вы сделаете процессор с меньшим числом исполнительных устройств, то вы не можете просто так выполнять код процессора с большим числом исполнительных устройств. Потому, что одна команда может переписывать регистр, используемый другой командой длинного слова. И если вы начнёте выполнять команды последовательно, то результат будет другим, нежели при параллельном выполнении. Или вам придётся так распределять регистры, чтобы команды не пересекались по зависимостям, что не улучшает эффективности использования регистров.

Практически все VLIW процессора не имеют прямой и обратной двоичной совместимости.

Последнее прямо запрещает делать линейки процессоров с одной системой команд, как делает ARM и даже Intel. В результате VLIW это практически всегда один представитель.

VLIW требует гигантского регистрового файла. Его никто не смог сделать быстрым и небольшим (что помогает сделать его быстрым). Даже Intel с его бешеными ресурсами имеет Itanium на частоте в полтора гигагерца, когда i7 на тех же процессах давно работает на частоте вдвое большей.

Плотность кода VLIW меньше RISC в несколько раз. RISC вдвое менее плотный, чем CISC x86. Это настолько серьёзная проблема, что для VLIW DSP делают специальные компиляторы, что часть программы выдают в виде стекового кода, для компактности.

Последнее. Составление расписания выдачи инструкций базового блока (не функции и не программы!) является NP-сложной задачей. Это когда и вычисление расписания, и проверка его на оптимальность являются NP-полными задачами.

В результате, если вы делаете VLIW процессор, вы сразу ставите на нём крест, как на процессоре общего назначения. MS Word на нём будет работать плохо, процессор для телефона и для сервера вы так не сделаете.

Все эти данные известны с 2006 года, примерно.

Поэтому Эльбрус 2СМ хорош, как пример реальной системы с реализованными для него сложными протоколами периферии. Мы можем. Как процессор он плох. Но это не мешает ему быть замечательным примером, что мы можем.
with Cat The Cat

Не могу молчать.

Итак, как конфигурируется память в FPGA. Память в FPGA двухпортовая, то есть, в неё можно читать и писать одновременно. Что прикольней, у неё можно конфигурировать ширину входов (на запись) и выходов (на чтение). То есть, я могу записывать, допустим, два байта, а читать четыре. При этом на запись есть маски, чтобы можно было записать один из байтов, не трогая другой.

Если это доступно на FPGA, то это доступно и на ASIC. Потому, что это почти тривиально.

Представим себе, что мы можем писать и читать сразу 8 регистров. В восемь регистров можно уложить счетчик команд, указатель стека возвратов, указатель стека данных, регистр с вершиной стека, и ещё четыре регистра на разные нужды. Это означает, что мы можем за один такт выполнить, практически, одну команду стековой машины.

Если у нас 64 регистра, то мы можем вести 7 таких машин на одном RISC ядре. Это означает, что мы можем иметь глубину конвейера у ядра в 7 шагов и полностью загрузить наше ядро. Мы, также, можем добавить признаки готовности к нашим машинам и у нас получится приятное OOO для стекового кода.

Почему 7 машин? Потому, что одно окно будет занято обычными регистрами RISC, включая регистр с константой 0.

Что это даст?

Во-первых, компактность кода. Код для стековой машины в стиле Форт в 2+ раз компактней кода однооперандной регистровой машины типа x86. При этом код x86 (не x86-64) в два+ раз компактней кода типичного RISC.

Те, кто хотят сослаться на Dalvik vs JVM, прошу заметить, что JVM стековая машина, но код в ней не в стиле Форта. Единственный возможный вызов в JVM это вызов метода, поэтому там нет вынесения одинакового кода в подпрограмму, как это принято в Форте.

Плюс, выполняя команды RISC в определенном окне стековой машины, мы можем сэкономить на адресации регистров - 3 бита вместо 6. Это 9 бит, то есть, 23 бита при сохранении кодирования вместо 32. Четверть код урезана просто так. Principled Thumb, так сказать.

Во-вторых, чрезвычайно дешевые зеленые нити и "hyperthreading". Дешевле, чем у библиотеки времени поддержки ghc. Переключение контекста в пяток тактов - самое то.

В-третьих, из-за разделения одного регистрового файла на несколько машин мы получим молниеносную посылку сообщений и/или транзакционную память на три-пять машинных слов.

В-четвертых, стековая машина чрезвычайно удобна для выполнения языков программирования с ленивой семантикой. См. TIGRE и Reduceron. ;)

Потребуется более сложный кэш данных - на два запроса (выборка команд и чтение/запись операндов/результата) одновременно.

Да, и сам регистровый код RISC никто не отменял. Достаточно дождаться окончания работы всех машин (состояние синхронизируется в регистры) и начать выполнять обычный код.

И напоследок можно это всё отлакировать сверху векторной машиной. С векторами слов в 128-256. Тогда стековая машина будет всего лишь управлять векторной, на которую и падёт проблема обеспечения производительности. По идее, это ещё и сократит размер кода.
with Cat The Cat

Умножение матриц.

Прочитал про алгоритм Кэннона.

Думается мне, его можно получить преобразованием из систолического алгоритма путём укрупнения вычислений на процессорах.

Я провёл эксперимент на своей давней модели машины потока данных, вроде, при увеличении размера обрабатываемых на одном узле подматриц получается ускорение работы.

В README дана командная строка, так вот вот чем больше сдвиг, задаваемый в параметре --taskOption=shift=n, тем быстрее выполняется умножение. При n=0 на одном узле выполняется 32 умножения матриц 1x1, n=1 - 8 умножений матриц 2x2, n=2 - 2 умножения матриц 4x4. При этом количество операций пересылки между процессорами (весьма затратная процедура, много затратней полезных операций сложения и умножения, которые считаются выполняющимися за один такт) значений падает вдвое с ростом размера подматрицы.

И напоследок алгоритмы умножения для сравнения. Простой алгоритм:
for (i=0;i < N;i&plus&plus)
    for (j=0;j < N; j&plus&plus) {
        C [i][j] = 0;
        for (k=0; k < N;k&plus&plus) {
            m = A[i][k] * B[k][j];
            C [i][j] = C [i][j] + m;
        }
    }
И алгоритм, по своим зависимостям и порядку выполнения наиболее приближенный к систолическому:
for (i=0;i < N;i&plus&plus)
    for (j=0;j < N; j&plus&plus)
        C [i][j] = 0;
for (k=0; k < N;k&plus&plus)
    for (i=0;i < N;i&plus&plus)
        for (j=0;j < N; j&plus&plus) {
            m = A[i][k] * B[k][j];
            C [i][j] = C [i][j] + m;
        }
Совершенно неправильное построение обращений к памяти с точки зрения эффективности на обычной машине. А вот на параллельной работает на ура.
with Cat The Cat

Reduceron.

Посмотрел из любопытства на исходники.

Во-первых, совершенно нет комментариев. В коде. ;)

Во-вторых, производительность на реальных задачах можно получить смелым делением заявленной производительности пополам, а то и втрое. Это хорошо работать с целыми числами на 96 МГц, попробуй работать с плавающей точкой, она ни в один такт не влезает (если только специально такт не растягивать).

Соответственно, ускорение по сравнению с x86 получается всего в три-пять раз, не в десять (у Reduceron на 96MHz 29% производительности x86 на 3GHz). ;)

Возможности расширения системы команд для плавающей точки я не усмотрел. Но говорю, там очень мало комментариев. ;)
with Cat The Cat

Детали реализации.

На прошедшем на прошлой неделе семинаре присутствовал молодой человек, читающий в Бауманке курс по процессорам. Я воспользовался возможностью и попросил его дать хотя бы немного информации о семействе Alpha AXP.

Когда дековцы собрались делать Альфу, они явно указали, что детали реализации не должны торчать наружу. Из-за этого Альфа стала практически самым передовым процессором того времени, "виртуальную машину" системы команд можно было интерпретировать, как угодно, главное - сохранить семантику.

Я снова пишу о процессорах, поскольку столкнулся с замечательным семейством команд системы команд MIPS. Они называются Branch-условие-Likely. О, это песня, эти команды.

У MIPS команда перехода захватывает на выполнение следующую команду, это называется "такт задержки команды перехода", ТЗКП, branch delay slot. Это сделано для увеличения общей производительности - не теряется такт вычисления условия, - а также это получается довольно просто и не надо делать специальную машину состояний в машине выборки и выдачи команд.

Так вот, команды BGEZL и подобные ей, пропускают команду в branch delay slot, если переход не был выполнен. В этом есть польза - можно в ТЗКП внести первую команду цикла, - но эта польза нивелируется следующими соображениями, изложенными в документации на команды: BGEZL вносит существенную задержку в случае отсутствия перехода, и её надо применять только в случае 98% и более вероятности перехода. А в документации на MIPS 4KM прямо указано, что команда устарела (deprecated) и её не надо использовать.

Итак, шаги.

Первый шаг - сделаем простой процессор, с наивысшим быстродействием на данный момент, внеся в спецификацию системы команд подробность реализации, тот самый ТЗКП. Оный ТЗКП приносит 16% увеличения скорости "внутри цикла длиной в 20 наносекунд", а в изменении архитектуры интерпретатора только мешается - и исключения обрабатывай по-другому, и зависимости считай на пятый стук бубна, в общем, беда. Но самая первый вариант будет элегантен донельзя, ничего лишнего, никаких пропусков тактов с помощью машины состояний.

Второй шаг - внести специальные команды, которые всё-таки заставляют внести в систему выборки и выдачи команд машину состояний, да ещё и посложнее, чем было бы раньше.

Третий шаг - ??? Точнее, указать на нецелесообразность использования таких команд за исключением особых редких случаев, а в некоторых вариантах документации прямо указать на запрет их использования.

Четвёртым шагом является "прибыль", конечно же.

Возвращаясь к началу моего поста, практически все процессора того времени содержали ту или иную деталь реализации, вытащенную наружу: MIPS, SPARC, PA RISC - ТЗКП, ARM - PC доступен, как регистр, но в момент его использования он должен равняться адресу команды 8.

Альфа стала приятным исключением. Вроде, Power PC тоже неплох. Система команд Cell BE не оставила неприятного впечатления, наоборот.

И когда я обнаружил, что свежий дизайн - OpenRISC 1200, - тоже содержит ТЗКП... Ну, когда я об этом вспоминаю, я криво улыбаюсь. ;)

PS
Ещё, кстати. В MIPS есть команды целочисленного сложения-вычитания, которые дают исключения при переполнении. Их никто в здравом уме не использует (в кодогенераторах ни в одном не видел), но они есть в доке и их надо поддерживать. В OpenRISC это тоже есть.

Для более простой реализации процессора лучше делать как можно меньше исключений - меньше логики, всё такое. Так вот господа из OpenRISC умудрились сделать команды умножения с приёмником-регистром и деления (с регистрами умножителя) бросающими исключение. Это означает, что деление становится блокирующей командой, её нельзя выполнять параллельно с другими командами. Они неожиданно для самих себя ухудшили производительность процессора.

При этом в MIPS эти же команды спокойно выполняются, ничего не бросая, только для DIV может быть неопределённое состояние. Переполнение деления заменяется проверкой и выполнением команды исключения - в тех случаях, когда проверка нужна. А это не столь уж и частые случаи.