среда, 11 января 2012 г.

Футурология - наука о предсказаниях

Почему футурологию можно назвать наукой? Да очень просто по определению, у нее есть метод прогнозирования и прогнозируемый результат. Развитие языка программирования...

Мой прогноз основывается на том, что сегодня составляет основу программирования и что может считаться языком сегодня, языком на котором я разговариваю с железяками.
Мы не признаем никакого С++ и основываем домыслы на С. С++ нужен как этап образования, а серьезные проекты пишутся все равно на Си. А вот что бывает поверх си, вот в чем вопрос. Практически в каждом проекте есть динамические данные. Берем с собой методы new и free. Однако, мир не так прост. Я бы добавил еще несколько менеджеров памяти для других распространенных целей.
Слайсы, я их применяю всегда когда дело касается списков или множества мелких объектов. Слайсы - это блоки памяти фиксированного размера выделяются из массива, накладные расходы = 1бит на слайс. Выделение и освобождение слайсов производится без использования циклов поиска, и не требует операции сбора мусора. Т/е это быстро рабоает и хорошо себя проявляет, когда дело касается очередей и списков.
Блоки, блоками хочется выделять память когда работа ведется с протоколами или файловой системой. Можно упростить работу по сбору мусора если блоки поддерживаются на уровне управления виртуальной памятью. Особенностью блоков может быть например возможность порождать их в одном приложении, а освобождать в другом.
Динамические строки, важный элемент - динамические байтовые массивы, или динамические строки. Когда программа занимается разбором строк или формирует пакеты сетевых протоколов, это необходимый инструмент.
Кварки - это такой механизм однозначного сопоставления строк и уникальных идентификаторов. Фактически использование идентификаторов вместо строк позволяет существенно ускорить разбор текстовых форматов и упростить организацию хранения данных. Например, кварки используются для ассоциативных массивов. Кварки мне на самом деле нужны в самом языке, потому что хочется уметь получать сопоставление уже на этапе компиляции а не на этапе исполнения или инициализации программы. Есть разряд программ, которые нельзя описать средствами языка Си, требуется предкомпиляция (препроцессор), это касается всевозможных интерпретаторов и компиляторов. Статические кварки от этого избавляют.
Векторизация и безграничная арифметика. В моих задачах, когда дело касается реализации кодеков, криптографии или алгоритмов упаковки данных, хочется описывать правила ускорения. Иногда хочестя уметь описать правила переноса в числе разрядностью 256 или 512. это не сложно на языке Ассемблера, но непонятно как описать на Си. Тут просто не хватает языковых конструкций для описания переносов и описания векторов, параллельности. Иногда я в своих программах пишу например такое:
x=a*x+b, y=d*y+c;
-- я имею ввиду, что две эти операции можно выполнять параллельно и в системе команд современных процессоров наверняка найдется команда которая позволит это сделать, а компилятор меня не понимает.
Векторизация бывает разная, например цикл состоящий из замеса (битовой операции XOR) и сдвигов и копирования данных можно упростить, только это не человеческая задача, она требует линейных преобразований выражения в аналитическом виде со стороны компилятора. Я всегда вижу куски алгоритмов, которые можно ускорить таким образом, но не имею терпения выполнять такие операции в голове или на листочке, особенно если там много циклов. Я бы сказал что существует потребность выполнять преобразования выражений и циклов в аналитическом виде, а потом применять компилятор. эту языковую конструкцию я вижу, как ключевое слово eval {блок}. Иногда чтобы две операции выполнялись параллельно их надо усложнить. Например, если в цикле видим y=g(x); x=f(y); можно выполнять параллельно, если два значения расчитываются независимо y=g(x); x=f(g(x)); Иногда цикл имеет смысл разбить на два и расчитывать x и y независимо. Как выразить эту оптимизацию. Кроче, не место в языке ручным оптимизациям, но как-то надо научить компилятор упрощать и преобразовывать выражения в аналитическом виде.
Конструкторы и деструкторы. Стал часто использовать статические конструкторы в своих программах, они позволяют подготовить глобальные статические данные до исполнения программ. Сейчас я это решаю при помощи атрибутов __attribute__((constructor)). Конструкторы - это функции которые выполняются перед main.
Программные модули. Динамическая регистрация модулей -- это не часть языка, но я использую этот концеп очень часто. Концепция модуля - программа, которая отлаживается отдельно. Добавление функциональной возможности в проект сводится к добавлению в список файов для компиляции, если прикомпилировали, то функция доступна. Большие проекты хорошо разрабатываются если имеют модульную структуру. Модуль добавляется автоматически в список типовых модулей с использованием функции-конструктора. Функции доступны по идентификатору функции. Можно сделать реализацию модулей на динамической линковке библиотек, но это все же другой механизм.
Атомарные операции. Ну вот есть еще один зверь, которого не удобно описывать средствами языка, а надо бы. Чисто математически можно добиться атомарности пользуясь всего одной операцией, любую атомарную операцию можно выразить через условную запись (LL/SC, load-linked/store-conditional) или через сравнение-и-замену (CAS, compare-and-swap).

1 комментарий:

  1. За это время то ли компилятор стал умнее, то ли я научился пользоваться компилятором. Теперь во всех моих алгоритмах, которые требуют быстродействия присутствует векторизация. Я уже привык писать алгоритмы с вектоизацией. Если быть объективным, в 12 году компилятор GCC еще не умел нормально использовать вектора и часто зависал на моих упражнениях. Теперь после версии примерно 4.8 проблем с описанием векторных операций не возникает, хотя это не часть языка Си, а его расширение. Атомарные операции явно пытаются стать частью языка, как и треды. см стандарт С11. LL/SC - это операции из архитектуры MIPS, разве кто-то помнит. Сейчас надо писать LDREX/STREX. Что-же будет с моими программами в будущем, какими они будут? Что в них такого появится, что языком Си описать не возможно? Я знаю что мне хочется добавлять в программы в текущий проект. Мне не хватает препроцессора и я пока даже не могу четко сформулировать что он делает. В программах я часто использую Кварки- однозначное соответствие строк и чисел. Чтобы при разборе форматов сравнивать не строки а идентификаторы ключевых слов. Про кварки я уже говорил, но как описать кварки статические, я это сейчас делаю с помощью конструктора. Перед началом работы инициализирую таблицу кварков (ключевых слов). Эту операцию мог бы делать компилятор или препроцессор, только что это за операция я не придумал. Другая проблема, о которой я думаю, и опять не понимаю, препроцессор или компилятор это должен делать. Я могу себе представить условную компиляцию и оптимизацию на основании констант. Например, если я использую конструкцию if(выражение){обработка} и значение выражения можно вычислить на этапе компиляции, то весь блок может быть оптимизирован или пропущен, как никогда не исполняемый. Сейчас передо мной стоит задача - выражение вычисляется на основе разбора текстового или бинарного формата, который является константой, сам файл константа, не изменится в процессе выполнения программы, как в таком случае выполнить оптимизацию. Ответ напрашивается: нужен такой препроцессор который нагенерит множество бессмысленных констант и подставит вместо выражения его значение. Частью препроцессора хочу видеть конфигурационный скрипт - программу. Пред-пред процессор. Мне нужен такой инструмент, который бы анализировал и исполнял код до компиляции. Уупс. Я уже тут писал про директиву языка eval{блок} -- это оно, мне нужно заставить компилятор поработать интерпретатором, перед выполнением компиляции кода.

    ОтветитьУдалить