Реальный рост скорости процессоров серии Intel - 80x86 и эффективность программ на языках фундаментального уровня.
Эффективность обработки процессором значений переменных объектов в регистрах процессора и в главной памяти ЭВМ.
Для сравнительного анализа и оценки скорости процессоров серии Intel - 80x86 были измерены времена работы циклов, включающих последовательности команд арифметических и логических операций, обработки процессором значений переменных объектов в регистрах процессора и в главной памяти ЭВМ, а также команд условного перехода.
Также - соответственно - вычислялась скорость работы процессора в миллиардах операций в секунду на последовательностях команд обработки значений объектов соответствующих типов, сведенных в следующую таблицу.
В первой колонке этой таблицы в модельных строках таблицы (это первая, четвёртая, седьмая, десятая, тринадцатая, шестнадцатая, девятнадцатая и 22-я строки таблицы) перечислен ряд моделей процессоров серии Intel-80x86:
DX4 - AMD DX4 - 100
PII - PentiumII - 500
P-4 - Pentium4 - 2400
Atl - Athlon64 - 1800
Atd - Athlon64 - 2860 - данные на один из двух процессоров
Duo - Core Duo - 1700 - данные на один из двух процессоров
Qad - Core2 Quad - 2500 - данные на один из четырёх процессоров
PX6 - Phenom II X6 - 2800 - данные на один из шести процессоров
Ci7 - Core i7 2600 - 3400 - данные на один из восьми процессоров
Далее, по колонкам таблицы, в модельных строках таблицы, перечислены измеренные значения скорости работы процессора в миллиардах операций в секунду на последовательностях команд обработки значений объектов соответствующего типа, в командах с адресацией соответствующего этим типам вида.
Во второй колонке этой таблицы, в модельных строках таблицы, перечислены измеренные значения скорости работы процессора в миллиардах операций в секунду на последовательностях команд обработки значений объектов типа "регистровое целое" - "Register Integer" в командах с адресацией вида регистр - регистр.
Во второй, пятой, восьмой, одиннадцатой, четырнадцатой и семнадцатой, и т.д. строках таблицы, приведены соотношения между быстродействием различных типов команд по соответствующим колонкам таблицы, и быстродействием основных команд - операций для обработки значений объектов типа "Static Integer Usual", расположенных в главной памяти, приведенным в шестой колонке таблицы.
Наиболее впечатляющими соотношениями внутри одной и той же модели процессора являются соотношения между быстродействием команд - операций для обработки значений объектов типа "Register Integer", и быстродействием основных команд - операций для обработки значений объектов типа "Static Integer Usual", расположенных в главной памяти.
Это то, что составляет отношение:
в 15,80 раза для модели PII-500,
в 11,49 раза для модели P4-2400,
в 10,41 раза для модели Athlon64-1800,
в 11,43 раза для модели Athlon64-2860, и
в 11,78 раза для модели AMD DX4-100.
И это - главные аргументы в пользу того вывода, что для создания быстрых программ надо максимально стремиться к программированию в среде команд - операций для обработки значений объектов типа "Register Integer".
Так же, впечатляющими соотношениями внутри одной и той же модели процессора являются соотношения между быстродействием команд - операций для обработки значений объектов типа "Register Integer + Condition", и быстродействием основных команд - операций для обработки значений объектов типа "Static Integer Usual", расположенных в главной памяти.
Это то, что составляет отношение:
в 30,77 раза для модели PII-500,
в 11,19 раза для модели P4-2400,
в 10,54 раза для модели Athlon64-1800,
в 8,721 раза для модели Athlon64-2860, и
в 8,78 раза для модели AMD DX4-100.
И это - главные аргументы в пользу того вывода, что надо последовательно максимально стремиться к программированию в среде команд - операций для обработки значений объектов типа "Register Integer", в сочетании с командами - операциями условного перехода.
В третьей, шестой, девятой, двенадцатой и шестнадцатой, и т.д. строках таблицы даны вычисленные значения отношения скорости работы процессора последующей модели, к скорости работы процессора предыдущей модели, на последовательностях команд обработки значений объектов этого же типа.
Так, скорость работы процессора модели PII-500, равная 0.695 миллиарда операций в секунду в 6,557 раза больше скорости работы процессора модели DX4-100, равной 0.106 миллиарда операций в секунду, на последовательностях команд обработки значений объектов типа "Register Integer".
А скорость работы процессора модели P4-2400, равная 4.641 миллиарда операций в секунду в 6,687 раза больше скорости работы процессора модели PII-500, равной 0.694 миллиарда операций в секунду, на последовательностях команд обработки значений объектов типа "Register Integer".
Из этих соотношений видно, что на последовательностях команд обработки значений объектов типа "Register Integer" происходит основной, и вполне закономерный, рост скорости обработки значений объектов данного типа, из всех перечисленных в таблице типов, обусловленный увеличением тактовой частоты, указанной сразу после марки процессора, в мегагерцах, и совершенствованием внутренней структуры процессоров.
Оценка конструктивных особенностей процессоров выходит за рамки данного обсуждения.
Однако, из этих оценочных соотношений видно, что на последовательностях команд обработки значений объектов типа "Register Integer", при переходе от модели DX4-100, к модели PII-500, при росте тактовой частоты шины в пять раз, происходит еще больший рост скорости работы процессора в 6,557 раза, вероятно, за счет большего параллелизма конвейерной обработки команд.
А при переходе от модели PII-500, к модели P4-2400, при росте тактовой частоты шины приблизительно еще в пять раз, происходит еще больший - в 6,687 раза, т.е. почти семикратный(!) - рост скорости работы процессора, вероятно, за счет того, что процессор P4-2400, работает на удвоенной частоте шины.
Третья колонка таблицы характеризует аналогичное увеличение скорости процессора на последовательностях тех же команд обработки значений объектов типа "Register Integer", к которым добавлены команды сравнения значений типа "Register Integer", и команды условного ветвления - "Branch on Condition" - перехода по условию.
Внушительное увеличение скорости процессора на последовательностях команд обработки значений объектов типа "Register Integer" и команды условного ветвления - "Branch on Condition", сокращенно - "Rgstr Intgr + Cond", при сравнении процессоров модели DX4-100 и PII-500, в 17,14 раза, получено, по всей вероятности, за счет предварительного вычисления вероятного перехода.
Однако оно вполне компенсируется небольшим увеличением скорости в 3,338 раза, при сравнении процессоров модели PII-500 и P4-2400.
Таким образом, общее увеличение скорости в 57,22 раза, при сравнении процессоров моделей DX4-100 и P4-2400 по этой последовательности команд, - "Rgstr Intgr + Cond", сравнимо, и даже больше, чем общее увеличение скорости в 43,78 раза, при сравнении процессоров этих же моделей на последовательностях команд обработки значений объектов исключительно, типа "Register Integer".
Четвёртая, пятая, и шестая колонки таблицы характеризуют увеличение скорости процессоров на последовательностях команд обработки значений объектов типа "Static Integer", размещаемых в главной памяти компьютера.
Разница в измерениях, в этих случаях, заключается в том, что зацикливание одинаковых последовательностей команд для обработки значений объектов типа "Static Integer", производится разными командами и способами построения циклов.
Магистральный путь автоматизации программирования.
Магистральный путь автоматизации программирования проходит через создание систем программирования на процедурно - ориентированных языках.
Изначально, - этот путь разветвился на два основных пути.
Первый путь, - это путь развития чисто операторных языков, в которых каждый элементарный оператор языка являлся изображением элементарной операции.
Языки первого типа, - это такие языки, типичным представителем которых является язык ассемблера, зачастую ранее называвшийся мнемокодом или автокодом [1], изображают множество несвязанных элементарных операций, каждая из которых, как правило, исполняется одной из машинных инструкций - команд процессора.
Второй путь, - это путь развития языков формул, в которых каждый элементарный оператор содержал, как правило, математические выражение в традиционной скобочной форме, с разным уровнем весов операций, изображающее множество связанных элементарных операций над константами и переменными, прародителем и типичным представителем которых является язык FORTRAN (FORmula TRANslator).
Магистральный путь автоматизации программирования, однако, часто объективно требует слияния обоих путей автоматизации программирования обратно, - в единый путь и подход к процедурно - ориентированным языкам, путь - обладающий достоинствами обоих указанных путей.
К таким, единым языкам операторных выражений, то есть, фактически, языков операторных формул, занимающим особое положение, относятся, к примеру, язык Форт [2] или отечественный проект языка АЛМО (Алгоритмический Машино - Ориентированный язык) [3].
Однако постфиксный способ формирования операторных выражений, в котором, объекты, то есть, - переменные или константы, самого действия, - операции или функции, предшествует знаку самого этого действия, или, так называемый, польский инверсный способ формирования операторных выражений, применяемый в этих языках, для формирования выражений, несмотря на его прозрачную универсальность, очень непривычен для восприятия человеком.
Это, безусловно, имеет место по причине особенностей логики человеческого мышления.
Это имеет место в силу того, что, - поскольку, в обычных национальных языках человеческого общения, прослеживается тенденция порядка слов в предложении повелительного наклонения, в котором, - основа - глагол - сказуемое, повелительного наклонения, что определяет действие, то есть, операцию или функцию, обычно, предшествует дополнению, которое определяет объект этого действия.
По этой причине, больше, и чаще, используется традиционный инфиксный способ формирования выражений, где, в двуместных операциях, знак операции самого действия имеет свое место между объектами, то есть, - переменными или константами, самого действия - операции.
В инфиксном способе, знак операции самого действия, предшествует, по меньшей мере, второму объекту, то есть, - переменной или константе, самого действия - операции.
Однако традиционный инфиксный способ формирования выражений имеет ряд существенных недостатков, которые и приводят к концептуальной неоднородности и излишней громоздкости инфиксного выражения.
Во-первых, - чисто традиционный инфиксный способ формирования выражений, является инфиксным, только для знаков операций.
Вызов функции здесь формируется префиксным способом.
В таком, префиксном способе, - глагол повелительного наклонения, который определяет действие - функцию, предшествует дополнениям, которые определяет объекты этого действия.
Во-вторых, инфиксный способ формирования выражений использует скобки - ограничители подвыражений.
Такие скобки, разбивающие выражение на иерархию ряда подвыражений, в том числе, подвыражений вычислений аргументов вызовов функций, - разрушают прозрачную линейную структуру выражения.
Более того, иерархия уровней элементарных операций, а в языке Си, к примеру, таких уровней до десятка, - дополнительно запутывают разработчика выражений, и он, зачастую, для ясности и определенности, вынужден вводить дополнительные пары, строго говоря, не нужных скобок, для компилятора, но требуемых, для лучшего понимания самой иерархической структуры этого выражения.
Надо чётко себе представлять, что такой способ записи выражений является историческим рудиментом от тех времён, когда выражения изображали только на бумаге, в основном - удобным только для изображения разноуровневых многочленов громоздких степеней и многоэтажных формул с громоздкими радикалами.
Такой способ записи выражений, конечно же близок рудиментарному племени феодальной иерархии завлабов, завкафедр и профессоров безмерно широкого вплоть до дилетантизма профиля, поскольку скачущему по верхушкам широко и далеко, нет времени, да и желания карабкаться до высот профессионала.
Ни к чему им это, поскольку в федально-околонаучной иерархии - источника званий, им и так хорошо, защитил за несколько лет - пару диссертаций и ходи королём или князем, и ни к чему им эти хлопоты, всю жизнь карабкаться до высот профессионала, - им достаточно властных командных высот.
Хорошо, что и из них, бывают, приятные, конструктивные исключения.
А часто ли программисты системных программ операционнх систем, информационных задач или задач символьной обработки, анализа и логического вывода - программируют высокостепенные многочлены или радикалы???
Конечно - нет, нет и нет!!!
Поэтому, в математическом выражении, отказ от иерархии уровней элементарных операций, приводит во многих случаях к лучшему пониманию самой иерархической структуры этого выражения, которое, в этом случае, приближается к языкам операторных выражений, то есть, фактически, к языкам операторных формул.
К таким, единым языкам операторных выражений, то есть, фактически, языков операторных формул, занимающим особое положение, относится и язык лингвопроцессорных выражений - Люкс (LUX - lingual unit's expressions), - короче Лингва, - который обычно используется в программировании, как язык компактных функций, что, в большой степени, определяет его эффективность и структурные концепции.
В Лингве вызов операции и функции - концептуально однородны и представляют собой список операторных звеньев, где, на первом месте списка, формируется знак операции-функции или идентификатор функции, а далее идет список операторных звеньев - операндов этой операции или функции.
Но, самым важным, концептуальным, изобретением, для изобретения всего способа формирования лингвопроцессорных выражений, является изобретение скобок - операций, где данные знаки скобки - операции - означают знаки операций для работы со стеком.
Исследования и разработки по созданию данного языка LUX, - Лингвы, - выполненные автором в течение более чем десятилетия, были направлены на создание системы программирования для программистов - профессионалов, которая помогает быстро разрабатывать программы высочайшего качества и быстродействия в удобной дружественной среде программирования, работающей с фантастически быстрой реакцией.
Для этих целей, язык LUX был создан как язык достаточно высокого уровня на концепциях структурного и объектно - ориентированного программирования, поскольку именно эти концепции, во многом, определяют уровень языка, для чего в него введены изящные операторы цикла, условные операторы типа IF-THEN-ELSE, SWITCH-CASE, а также безусловные операторы типа SKIP-BREAK, благодаря которым удалось практически полностью отказаться от безусловных переходов типа GO TO.
Язык Люкс имеет столь же полный набор, что и в Си, но более компактных чем в Си, структурных операторов типа IF-ELSE и DO-WHILE-FOR, что и язык Си, к тому же язык Люкс также, как и Си, имеет операторы SWITCH.
Это означает, что язык Люкс имеет не меньшие структурные возможности структурного программирования, чем язык Си, что разительно отличает язык Люкс от языка макроассемблера, но по быстродействию и компактности исполняемого кода язык Люкс имеет не меньшие возможности, чем язык макроассемблера.
Таким образом, язык Люкс объединяет лучшие достоинства языков Си и Макроассемблера, избавляясь от их недостатков.
Язык LUX используется как язык компактных функций, или процедур, эффективно использующих среду регистров процессора, глобальных и локальных переменных вызывающей подпрограммы, что еще в большей степени определяет его эффективность и структурные концепции.
В языке LUX применена запись выражений в нетрадиционной постфиксно-префиксной форме, предельно подобной обычной инфиксной форме, что позволяет записывать выражения и транслировать их более эффективно, чем в традиционной скобочной форме.
Для получения эффективного машинного кода язык должен содержать именно ту систему арифметических, логических и условных операторов, которую интерпретируют современные компьютеры.
Степень эффективности программ, разработанных на языке LUX, практически максимальна, также как и равная степени эффективности программ, разработанных на языке ассемблера, тогда как удобства разработки выше, чем на языке высокого уровня, а, тем более, на языке ассемблера, в основном благодаря тому, что скорость компиляции и сборки программ в готовые загрузочные модули практически мгновенна на современных компьютерах.
И это чрезвычайно важно для работы в эффективном режиме скоростного диалога с истинно диалоговой реакцией компьютера.
Функции ввода-вывода и другие стандартные функции языка LUX написаны на самом языке LUX, что позволяет включать их в основную программу в режиме скоростной компиляции, в том числе и из библиотеки классов объектов, обладающих свойствами инкапсуляции, наследования и полиморфизма на основе позднего связывания.
Эти свойства, а также механизм динамической загрузки функций и объектов позволяют разрабатываемой программе иметь высокую степень динамизма в манипулировании объектами.
В системе программирования на языке LUX используется режим работы со встроенным редактором исходного текста, в котором отладка программ происходит вообще без обращений к магнитным дискам, и программист лишь сам инициирует в нужные моменты сохранение на магнитном диске не только отредактированных, но и отлаженных вариантов программ.
Такой режим отличается фантастически быстрой реакцией компьютера и скоростью отладки программ, только и позволяющей программисту работать эффективно и с удовольствием.
А то, что электроны в ЭВМ уже движутся, как правило, с релятивистскими субсветовыми скоростями в гигагерцовом диапазоне тактовых частот процессоров ЭВМ, ставит нас перед фактом, что такого рывка производительности процессоров ЭВМ, какой был в прошлое десятилетие, в исторической перспективе уже не будет, поскольку это противоречит законам электродинамики и самой природы.
В связи с этим, один из классиков программироваия Н.Вирт до сих пор поднимает вопрос о, так называемых, "жирных" программах, с неэффективным исполняемым кодом, сделанных наспех, в расчёте на постоянный рост производительности процессоров.
Так, вот, эта масленница, уже ушла в прошлое.
И перед тем, как погрузиться в ещё намного более глубокую и мутную пучину параллельного программирования на многопроцессорных средах, стоит подумать и о том, не рано ли мы сбрасываем со счетов, программы, с эффективным исполняемым кодом, разработанные по нашим старым добрым последовательным алгоритмам, да и параллельные программы на языке Люкс во многих случаях могут быть гораздо эффективнее по компактности исполняемого кода и его быстродействию.
Такой эффективности, к которой призывает и Н.Вирт, призван и служить язык лингвопроцессорных выражений - Lingual Units Expressions - LUX.
Этапы исследований и разработок Лингвы.
Первоначальная версия LUX была разработана для MS DOS и процессора Intel 8086, использующего сегментную модель главной памяти, и только допускающего бессегментное программирование в пределах одного сегмента, размером 64 килобайта, что позволяло создавать только маленькие бессегментные программы.
В остальных случаях приходилось использовать модель памяти, с множеством сегментов, что требовало более тщательного, профессионального уровня программирования, усложняло отладку программ и увеличивало сроки их разработки.
В этих же случаях было необходимо применение действий с двойной точностью над адресными указателями, а зачастую и над данными, что еще в большей степени увеличивало громоздкость программы.
И, наконец, в новых компьютерах с расширенной памятью MS DOS позволяла ограниченно использовать расширенную память, хотя и как быструю, но внешнюю, по отношению к программе, память, и не позволяла прямое распределение этой памяти под переменные, константы и исполняемый код разрабатываемой программы.
Процессоры Intel серии 386, 486 и Pentium позволяют прямую бессегментную адресацию всей главной памяти, а также непрерывные четырехбайтовые адресные указатели и целочисленные данные, над которыми производятся действия с одинарной точностью.
Однако, эти возможности процессоров не были реализованы в MS DOS, за редкими исключениями, указанными здесь выше.
Более мощные и универсальные возможности, связанные с использованием виртуальной памяти, реализованы в многозадачных операционных системах OS/2, Windows-95 и UNIX.
Однако, эти возможности оказались и более громоздкими: первые 4 - 8 мегабайт главной памяти занимает операционная система, к тому же виртуальная память была заметно медленнее реальной.
В системе программирования LUX, работающей под MS DOS, реализована компромиссная, оптимальная для многих приложений бессегментная операционная среда, в которой используются операции с обычной точностью над четырехбайтовыми целочисленными данными, адресными смещениями и указателями, позволяющая напрямую распределять и использовать всю главную (в том числе расширенную), реальную, память, работающую заметно быстрее виртуальной.
Такая среда могла быть использована для любых задач, однако она могла быть просто незаменима для задач, требующих всей главной памяти и максимального быстродействия, в частности задач с громоздкими вычислениями, с быстрой реакцией, в том числе задач сопряжения с реальными объектами, с обработкой результата в реальном масштабе времени.
Используя данную среду, Вы используете дорогостоящую главную память, включая расширенную, только для своей задачи.
Спектр применения языка LUX может быть весьма широким.
Автор удачно применял этот язык и для задач системного программирования, и задач компьютеризации управления.
В этих областях приложений, язык LUX использовался для создания диалоговых мониторов - оболочек системных программ и программ компьютеризации управления, текстовых редакторов и программ просмотра текстовых файлов.
В задачах компьютеризации управления язык был использован для разработки подсистем типа расчета заработной платы и учета кадров предприятия, работающих с базами данных на основе стандартных dbf - файлов, использовавшихся во многих системах управления базами данных для IBM PC - совместимых компьютеров.
Язык LUX может быть удачно применим во всем необъятном спектре задач символьной обработки текстовой информации.
Автору представляются весьма широкое возможности использования языка в задачах компьютеризации управления технологическими объектами и процессами в реальном масштабе времени для сбора и обработки данных с измерительных устройств и датчиков с наивысшей скоростью обработки данных достижимой на конкретном компьютере, установленном на связи с объектом и минимальным временем реакции компьютера на события в реальном объекте.
Язык LUX может быть использован в задачах системного программирования для разработки операционных систем, их многочисленных отдельных компонентов и обслуживающих программ - утилит, а также систем программирования на различных языках.
Ярким примером такого использования является создание самой системы программирования на языке LUX, на котором разработаны все ее компоненты, в том числе, библиотекари классов и динамических модулей, редактор текстов и, наконец, сам компилятор языка LUX, который целиком разработан на языке LUX, и является классическим образцом технологической версии самокомпилирующегося компилятора, версии, использующейся для промышленной разработки программ.
Другим ярким примером такого использования является создание компонента операционной системы MS DOS - бессегментной операционной среды для программ обработки, использующих всю наличную главную память для подпрограмм и данных в компьютерах, имеющих главную память объемом от нескольких мегабайт до десятков мегабайт.
В этой операционной среде используется модель непрерывной главной памяти, так называемая FLAT - model, позволяющая адресовать напрямую всю наличную главную память для подпрограмм и данных с прямым использованием 32-х - разрядных данных и адресных указателей, обрабатываемых 32-х - разрядными процессорами типа Intel 80х86.
В целом, язык LUX является машинно-ориентированным, и полное множество языка, ориентировано на разработку программ высокой эффективности, хотя и не имеющих свойства мобильности.
Такие программы не могут быть переносимы с одного компьютера на другой путем простой перекомпиляции и требуют определенной переработки.
Однако, в языке LUX выделяется мобильное подмножество языка, которое ориентировано на разработку программ, имеющих свойство мобильности.
Такие программы могут быть переносимы с одного компьютера на другой путем простой перекомпиляции.
Для оценки эффективности результатов трансляции с различных языков программирования выбран фрагмент программы часто применяемый для обработки символьной строки на языке Си.
Выбранный фрагмент для иллюстрации различий в эффективности трансляции с различных языков является примером изящного оператора языка Си
while(*ptra++=*ptrb++);
который применяется в языке Си для копирования строки символов.
Фрагмент программы на Си, приведенный ниже:
char stra[256],strb[256],*ptra,*ptrb;
main() { ptra=stra; ptrb=strb; while(*ptra++=*ptrb++); }
приводится в виде соответствующего фрагмента на языке ассемблера для процессора Intel 8086 и Pentium.
0000043C: C7 06 8A 04 8A 02 mov [048A],028A
00000442: C7 06 8C 04 8A 03 mov [048C],038A
00000448: 8B 1E 8C 04 mov bx,[048C]
0000044C: FF 06 8C 04 inc [048C]
00000450: 8A 07 mov al,[bx]
00000452: 8B 1E 8A 04 mov bx,[048A]
00000456: FF 06 8A 04 inc [048A]
0000045A: 88 07 mov [bx],al
0000045C: 0A C0 or al,al
0000045E: 75 E8 jne 00000448
00001153: C70534B6400034B44000 mov d,[00040B634],00040B434
0000115D: C70538B6400034B54000 mov d,[00040B638],00040B534
00001167: A138B64000 mov eax,[00040B638]
0000116C: FF0538B64000 inc d,[00040B638]
00001172: 8A10 mov dl,[eax]
00001174: 8B0D34B64000 mov ecx,[00040B634]
0000117A: FF0534B64000 inc d,[00040B634]
00001180: 8811 mov [ecx],dl
00001182: 84D2 test dl,dl
00001184: 75E1 jne .000001167
Это самый оптимальный вариант данного фрагмента, без использования регистровых переменных, содержит 10 команд, из них 8 в цикле, занимает 36 байт для MS DOS и 51 байт для Windows-32.
Варианты получены оптимизирующими трансляторами Турбо Си для MS DOS и C-Builder для Windows-32.
Сравнение вариантов программ полученных трансляторами Турбо Си для MS DOS и C-Builder для Windows-32 явно опровергают аргументы оппонентов, что более современные трансляторы так уж намного больше оптимизируют программу, что делают её более оптимальной, чем может разработать программу квалифицированный программист на языке Люкс, и точно также на языке ассемблера.
Другие варианты занимают от 12 команд, из них 8 в цикле, длиной 38 байт до 29 команд, из них 18 в цикле, длиной 105 байт.
Различия определяются уровнем оптимизации компилятора и выбранной односегментной или многосегментной моделью памяти.
Различия также показывают, что эффективность результата трансляции - вопрос далеко не праздный, поскольку различия в результатах трансляции могут быть весьма существенными.
При использовании регистровых переменных в языке Си, фрагмент программы приобретает следующий вид:
char stra[256],strb[256];
main() { register char *ptra,*ptrb;
ptra=stra; ptrb=strb; while(*ptra++=*ptrb++); }
После компиляции оптимизирующим компилятором Micrоsoft Си, версии 5.1, программа приводится в виде соответствующего фрагмента на языке ассемблера для процессора Intel 8086.
00000209: 57 push di
0000020A: 56 push si
0000020B: BE 10 00 mov si,0010
0000020E: BF 10 01 mov di,0110
00000211: 8A 05 mov al,[di]
00000213: 47 inc di
00000214: 88 04 mov [si],al
00000216: 46 inc si
00000217: 0A C0 or al,al
00000219: 75 F6 jne 00000211
0000021B: 5E pop si
0000021C: 5F pop di
Этот фрагмент программы, длиной в 20 байт, содержит 12 команд, из них 6 в цикле.
Для сравнения, аналогичный фрагмент на языке LUX:
F,strb T,stra [ . : .]<>0 \к тому же - более компактный, чем на Си\
приводится в виде соответствующего фрагмента на языке ассемблера для процессора Intel 8086.
00000A2F: BE 06 01 mov si,0100
00000A32: BF 06 00 mov di,0000
00000A35: AC lodsb
00000A36: AA stosb
00000A37: 3C 0D cmp al,00
00000A39: 75 FA jne 00000A35
Этот фрагмент программы, длиной в 12 байт, содержит 6 команд, из них 4 в цикле.
Резюме результатов трансляции показывает, что даже при использовании регистровых переменных в языке Си, даже после компиляции оптимизирующим компилятором Micrоsoft Си, версии 5.1, порождается фрагмент программы, длиной в 20 байт, который содержит 12 команд, из них 6 в цикле.
Полное подмножество языка LUX, порождает фрагмент программы, длиной 12 байтов, содержащий 2 команды в заголовке цикла и 4 команды в теле цикла, что почти в два раза эффективнее по занимаемой памяти и, по меньшей мере в полтора раза эффективнее по числу обращений к главной памяти и, вследствие того, по времени выполнения фрагмента программы.
Программистам, не представляющим в деталях языка ассемблера, нет необходимости изучать в деталях приведенные здесь фрагменты на языке ассемблера, поскольку они приводятся, в основном, для оценки объема этих фрагментов.
Детальное же исследование и сопоставление фрагментов, транслируемых с различных языков программирования, только и показывает, что только программы, транслируемые с языка LUX, имеют эффективность эквивалентную эффективности программ, транслируемых с языка ассемблера.
Приведенные примеры показывают, что, даже при использовании регистровых переменных в языках высокого уровня, и даже после компиляции оптимизирующими компиляторами, при использовании традиционных языков высокого уровня, не представляется возможным быстро и эффективно разрабатывать программы по уровню качества и быстродействия, приближающиеся к эффективности, которую имеют ассемблерные программы.
Это же - прямо подтверждают и исследования других разработчиков:
"Версии Паскаля, выдающие машинный код, позволяют приблизиться к эффективности выполнения, которую имеют ассемблерные программы, но не более, чем приблизиться: следует учесть изначальную неэффективность программ, полученных с помощью компилятора с любого языка высокого уровня" [2].
Для иллюстрации быстродействия системы программирования на языке Люкс достаточно сказать, что самокомпилирующийся компилятор языка Люкс, составляющий около 800 строк компактного текста на языке Люкс, содержащий около 8000 операторов этого языка, компилировал сам себя примерно за одну секунду.
Это было даже на черепашьи тихоходном по современным меркам IBM PC XT - совместимом компьютере, с процессором Intel 8086, работающем на тактовой частоте 5 мгц и имеющем индекс производительности по программе Norton Sysinfo равный единице.
На компьютере с процессором Intel 80286, имеющем индекс производительности по программе Norton Sysinfo равный всего 17.5 , компилятор языка Люкс компилировал сам себя уже за треть секунды, и это уже приемлемая диалоговая реакция.
На не самом быстроходном, по тогдашним, современным меркам, компьютере Intel 80486 DX4 - 100, имеющем индекс производительности по программе Norton Sysinfo равный 198.6, компилятор языка Люкс компилирует сам себя примерно за пять сотых секунды, что является фантастически быстрой диалоговой реакцией компьютера для такой достаточно большой программы.
Не смотря на значительный рост объема компилятора языка Люкс, на процессоре PII-500 время самокомпиляции уменьшилось до 16 микросекунд, а на процессоре P4-2400, - время самокомпиляции уменьшилось до 1 микросекунды.
Это свидетельствует о практически исчезающим по времени этапе трансляции и сборки в общей технологии отладки программы.
Разработчик практически не замечает этого этапа, и у него создается впечатление, что он работает не с транслятором, а с интерпретатором, который каждый раз, по необходимости, немедленно интерпретирует, т.е. выполняет, программу.
По видимому ощущению, - это происходит сразу после того, как в нее внесены, через встроенный редактор текста, текущие изменения, необходимые в процессе разработки и отладки программы.
При этом, программу интерпретирует сам процессор, и эффективность быстродействия выполняемой программы столь же максимальна, как и программы скомпилированной с языка ассемблера, и ее диалоговая реакция, также, максимально быстра для конкретного компьютера и конкретного алгоритма отлаживаемой программы.
Такая система программирования практически устраняет известную дилемму об использовании быстрых, но не оптимизирующих, компиляторов (или их режимов) для отладки программ и их алгоритмов, с последующей компиляцией отлаженных программ через оптимизирующий компилятор в оптимизирующем режиме.
Этой дилеммы для языка LUX не существует поскольку компилятор языка LUX и сам - является очень быстрым, и исполняемый код, генерируемый этим компилятором, практически не требует дополнительной оптимизации так как этот код, по эффективности, равнозначен коду программы, полученной с языка ассемблера.
Программы на языке LUX очень компактны и легко обозримы для разработчика, который, при умелой разработке компактных функций, концентрирует целиком свое внимание на конкретной функции, отлаживаемой в данный момент, которая, как правило, целиком размещается в видеокадре редактора текста на видеомониторе.
Программа запускается мгновенно, щелчком клавиши, на счет с часто мгновенной выдачей результата и, обратно, щелчком той же клавиши, происходит возврат в редактор текста в ту же строку отлаживаемой функции по простому циклическому сценарию: щелчок - исходный текст (корректировка), щелчок - результат (просмотр).
К примеру, автор, для тестирования статистической надежности программы, обрабатывающей прерывания в реальном времени, пользуясь таким удобным свойством, устраивал часовой прогон трансляции - счета программы, просто придавив эту клавишу большой книгой по программированию.
Резюмируя изложенный материал, необходимо еще раз подчеркнуть основные достоинства системы программирования LUX.
1. Компактность и обозримость (часто выше чем в Си).
2. Модульная, структурная и объектная ориентированность.
3. Библиотеки классов объектов, хранимые в машинном коде.
4. Компактность исполняемого кода (как в ассемблере).
5. Быстродействие исполняемого кода (как в ассемблере).
6. Диалоговая реакция (быстрота) при трансляции и сборке.
7. Встроенный редактор текста с диалоговым сценарием.
8. Различные модели памяти, включая COM и FLAT-32 модели.
***
Любому программисту должно быть понятно, что на языке ассемблера можно разработать самую эффективную программу для решения данной задачи, поскольку язык ассемблера позволяет изобразить любую команду процессора и любую самую эффективную цепочку команд процессора, реализующую алгоритм решения данной задачи.
Но абсолютно тот же логический постулат можно достоверно дать и для языка Люкс, то есть:
Любому программисту должно быть понятно, что на языке Люкс можно разработать самую эффективную программу для решения данной задачи, поскольку язык Люкс позволяет изобразить любую команду процессора и любую самую эффективную цепочку команд процессора, реализующую алгоритм решения данной задачи.
Любому программисту должно быть понятно, что трудоёмкость разработки программы на языке Си меньше, чем на языке ассемблера, исключительно за счёт более эффективных свойств структурного программирования в языке Си, нежели чем в языке ассемблера.
Но абсолютно тот же логический постулат можно достоверно дать и для языка Люкс, то есть:
Любому программисту должно быть понятно, что трудоёмкость разработки программы на языке Люкс меньше, чем на языке ассемблера, исключительно за счёт более эффективных свойств структурного программирования в языке Люкс, нежели чем в языке ассемблера.
Любому программисту должно быть понятно, что для любого структурного агрегата-оператора языка Си, по существу можно видеть наличие точно такого же по назначению структурного агрегата операторов языка Люкс, а именно:
СТРУКТУРНЫЙ ОПЕРАТОР IF-THEN
if ( cond() ) exec() ; <-------> @cond ?- @exec !
СТРУКТУРНЫЙ ОПЕРАТОР IF-THEN-ELSE
if ( cond() ) exec() ; else exed() ; <-------> @cond ?- @exec ? @exed !
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА WHILE
while ( cond() ) body() ; <-------> [ @cond ?- @body ]
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА DO-WHILE
do body() ; while ( cond() ) ; <-------> [ @body @cond ]<>0
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА FOR ++
for ( i = 0; i <= delta; i++ ) body(); <---> B:=0 [ B<=delta @body ++B ]
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА FOR --
for ( i = alpha; i > 0; i-- ) body(); <-------> [alpha @body ]-
СТРУКТУРНЫЙ ОПЕРАТОР СРАВНЕНИЯ С ВЕТВЛЕНИЕМ
if ( b>c ) exec() ; <-------> B>C @exec !
СТРУКТУРНЫЙ ОПЕРАТОР СРАВНЕНИЯ С ВЕТВЛЕНИЕМ
if ( b>c ) exec() ; else exed() ; <-------> B>C @exec ? @exed !
СТРУКТУРНЫЙ ОПЕРАТОР СРАВНЕНИЯ И ЦИКЛА WHILE
while ( b>c ) body() ; <-------> [ B>C @body ]
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА WHILE И СРАВНЕНИЯ
do body() ; while ( b>c ) ; <-------> [ @body B]>C
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА FOR++ И СРАВНЕНИЯ
for ( b = 0; b<=d ; b++ ) body(); <-------> B:=0 [ B<=D @body ++B ]
СТРУКТУРНЫЙ ОПЕРАТОР ЦИКЛА FOR-- И СРАВНЕНИЯ
for ( c = b; c > 0; c-- ) body(); <-------> [B @body ]-
***
Как видно, язык Люкс имеет тот же набор более компактных структурных операторов типа IF-ELSE и DO-WHILE-FOR, что и язык Си, к тому же язык Люкс также как и Си имеет операторы SWITCH.
Это означает, что язык Люкс имеет не меньшие структурные возможности структурного программирования, чем язык Си, что разительно отличает язык Люкс от языка макроассемблера, но по быстродействию и компактности исполняемого кода язык Люкс имеет не меньшие возможности, чем язык макроассемблера.
Таким образом, язык Люкс объединяет лучшие достоинства языков Си и Макроассемблера, избавляясь от их недостатков.
***
Я вовсе не призываю себя или кого-либо сразу бросать программировать на любых существующих языках, но программирование на языке Люкс может существенно расширить каждому свой диапазон возможностей и инструментов программирования, поскольку язык Люкс очень эффективен в разработке часто используемых стандартизованных объектных функций и инструментальных программ.
При конструктивном подходе и взаимном интересе я буду рад помочь любому, действительно - желающему того, в практическом освоении системы программирования на языке Люкс.
Это помогло бы Вам в более глубоком освоении самого искусства программирования, и у Вас был бы больший диапазон выбора языков и инструментов программирования.
Удачи Вам!
E-mail: pancov@mail.ru
Copyright (c) 1995-2011
Victor M. Pancov. Obninsk, Russia.
В.М.Паньков,249020 Обнинск, Россия.