Pull to refresh
89
0
Send message

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

Но и он тоже не спасет ((

"То бензин, а то - дети" (с) х/ф "Джентельмены удачи"

Констант много, а такая одна)) Если нужна таблица Менделеева, то заголовочный файл - к месту. А ради одной константы создавать его не хочется. Кроме этого, в FPU есть аппаратная команда загрузки ПИ, а команды загрузки Больцмана нет )). Компилятор должен стараться использовать аппаратные возможности. По такой логике надо было бы добавить в компилятор еще и 4 аппаратные константы логарифмов, но лень - не используем мы их.

Если Вы имеете ввиду "Intel® 64 and IA-32 Architectures
Optimization Reference Manual", то там не говорится, что "сохранены только для совместимости". Там, например утверждается, что

"Использование скалярного кода SSE/SSE2 вместо кода x87 может обеспечить значительное повышение производительности при использовании микроархитектуры Intel NetBurst и скромное преимущество при использовании процессоров Intel Core Solo и Intel Core Duo."

А кроме этого, изначально речь шла о триногометрических функциях, которых нет в SSE. Единственная команда FCOS во время выполнения не обращается к памяти, что сейчас очень ускоряет работу. Кстати, во время ее выполнения можно заниматься, например, целыми вычислениями.

Использование 80 бит в FPU вместо 64 в SSE2 замедляет работу, но зато намного корректней результат округляется до 64 бит.

И если в игрушках этого не требуется, то во многих задачах требования к точности сосвсем другие. Например, один градус отклонения от надира на высоте орбиты МКС - это 7 км на поверхности Земли. В игрушке наплевать, что монстр чуть-чуть не там, где был бы "в натуре". А в реальных задачах может и не наплевать.

Поэтому вычисления FPU более точные, а для триногометрических (и трансцендентных) функций и более быстрые.

А у меня в системной библиотеке вот так

PUBLIC COSD:                    ;ВЫЗЫВАЕТСЯ ИЗ PL/1

;---- ПЕРЕВОД ГРАДУСОВ В РАДИАНЫ ----

      MOV	RAX,[RBX]
      FILD16	ГРАДУС
      FLDPI
      JC	@

;---- ДЛЯ FLOAT-32 ----

      FMUL32	[RAX]
      FDIVR
      JMPS	CS1

;---- ДЛЯ FLOAT-64 ----

@:    FMUL64	[RAX]
      FDIVR
      JMPS	CS2

PUBLIC COS:                     ;ВЫЗЫВАЕТСЯ ИЗ PL/1

      MOV	RAX,[RBX]	;АДРЕС АРГУМЕНТА
      JC	@

;---- ДЛЯ FLOAT-32 ----

      FLD32	[RAX]		;ЗАГРУЗИЛИ АРГУМЕНТ
CS1:  FCOS
      POP	RAX
      LEA	RSP,[RSP]-8
      FST32P	[RSP]
      JMP	RAX

;---- ДЛЯ FLOAT-64 ----

@:    FLD64	[RAX]		;ЗАГРУЗИЛИ АРГУМЕНТ
CS2:  FCOS
      POP	RAX
      LEA	RSP,[RSP]-8
      FST64P	[RSP]
      JMP	RAX

      DSEG

ГРАДУС DW 180

Команды SSE* предназначены для параллельного выполнения одной операции с разными наборами операндов и непосредственно отношения к алгоритмам вычисления триногометрических функций не имеют. Насколько мне известно, в современных FPU триногометрические функции вычисляются полиномами Чебышёва, а квадратный корень - по методу Ньютона.

Дизассемблировав несколько программ, использующих косинус, я не смог найти ни одной, задействующей команду fcos.

Вспоминается анекдот "А Вы куда звонили, сэр?"

Встроенные в язык sin, cos или, например, арктангенс, для процессоров x86 естественно реализуются встроенными функциями FPU. Именно для этого они в FPU и вводились. Другое дело, что для игрушек часто достаточно очень приближенных значений.

В FPU есть также замечательная функция sincos, которая сразу считает и sin и cos, быстрее, чем отдельными расчетами. При этом sin и cos часто идут такими парами, например, в комплексных числах.

В используемом нами PL/1-KT из-за этого даже добавлена встроенная функция sincos и она активно используется, например, при расчете орбитальных данных.

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

следует пояснить, что в данном случае означает "нестрогая типизация".

Указатель в числовую переменную, например, в языке присваивать нельзя.

А выражение '2'+2 переведется в 4 для fixed, в 4e0 для float и в '4' для переменной типа строка. Т.е. всего лишь числа могут быть представлены в разных видах, (почему-то сейчас это называется разными типами) в том числе, в виде строк в кавычках. На мой взгляд, это достаточно строго.

Поделюсь некоторыми деталями появления PL/I на ПК.


В 1980 году нашлись люди, озаботившиеся переносом этого языка на мелкие компьютеры. Одним из первых был некий д-р Роберт Фрайбургхаус.
Он решил сначала немного урезать IBM-ский вариант языка и не тащить всякую экзотику вроде аглийской денежной системы в типах констант.
Фрайбургхаус собрал нечто вроде конференции по разработке подмножества языка и пригласил на нее Г. Килдэла. Килдэл имел за плечами опыт сопровождения транслятора PL/I в военно-морском институте. Но главное – он был специалистом №1 по микропроцессорам и разработчиком ОС. Язык PL/I ему сильно не нравился и он бы никуда не поехал, но по случайности конференция была в том же городе и на той же улице, где он жил. А кроме этого, Роберт обещал бесплатные обеды)) Когда Килдэл пришел, оказалось, что произошло недоразумение – Фрайбургхаус думал, что PL/M – это не полуассемблер, а прямо PL/I на микропроцессоре и пригласил Гарри как докладчика и консультанта. А выяснилось, что ни докладывать, ни консультировать нечего.

Но случилось удивительное – Гарри послушал выступления и предложения урезать PL/I ему понравилось. И он решил создать транслятор с этого подмножества для 8080, а потом и для 8086. Кстати, написаны они были на PL/M. Сейчас бы это подмножество назвали новым языком, но тогда так было не принято. Трансляторы PL/I-80 и PL/I-86 появились в 1982 и 1984 гг. Их и сейчас можно разыскать в сети. Позже подмножество было оформлено стандартом и ANSII и ISO.

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

Итак, все было подготовлено к массовому использованию PL/I на ПК. Но IBM по не техническим причинам не стала снабжать свои IBM-PC трансляторами Килдэла и история ИТ пошла по-другому.

Поймите меня правильно, развитие средств программирование объективно требовалось бы все равно . И был бы в основе последующего развития языков на ПК PL/I или Си (как вышло в действительности), все равно были бы созданы языки типа Java или Rust или Питон. Только все бы это было быстрее и качественнее сделано без бесконечного изобретения заново. И не нужны были бы лямбды, поскольку была бы с самого начала блочная структура и вложенные процедуры))

Подмножество «G» PL/I получилось компактным и, на мой взгляд, более человечным, сохранив дух языка. Например, в языке если не указан куда идет ввод-вывод, он идет в стандартные файлы SYSIN и SYSPRINT. В реализации Килдэла по умолчанию SYSIN – клавиатура, SYSPRINT – экран. Ну, очевидно же и всем понятно. И без всяких заумных DD-операторов времен перфокарт.

В языке много всяких любопытных мелочей, вызванных проявившимися проблемами при практическом использовании. Например, есть ON-оператор обработки прерывания, REVERT-отмена обработчика (например при выходе из подпрограммы) и SIGNAL-имитация прерывания при отладке (и не только). Но потребовался еще оператор RESIGNAL. Он нужен вот для чего. Произошло прерывание и системная библиотека вызвала Ваш обработчик. Внутри обработчика анализируете данные и вдруг видите – мама дорогая! – это прерывание было не для Вас. В этом случае ставите в тексте обработчика RESIGNAL. Т.е. это не тот обработчик, ищи другой подходящий. Сейчас многие такие вещи само-собой разумеющиеся. Но полвека назад это было новаторство, которое потом и пришлось переизобретать.

На мой взгляд, гораздо важнее сделать эргономичный переключатель русский/латинский, а не этот "ку с приседанием", как сейчас.

До эпохи Windows выпускались калавиатуры с отдельными клавишами "русская/латинская постоянная" и "русская/латинская при нажимании и удерживании". Это было гораздо удобнее.

Однако мой выбор (на личном опыте) "русская/латинская" в виде ножной педали. Реально удобно и эргономично, без шуток.

Термин "компиляция" основан не на английском, а на латинском языке. См., например, Вики "литературная компиляция"

Все-таки ветер дует не от того, что деревья качаются. Кроме, как для XMM такое ограничение было не нужно. А сейчас AVX-256/AVX-512 еще пламенный привет передают. Там с выравниванием еще печальнее. Лучше бы спрятали свое выравнивание внутрь и не морочили людям головы.

Боже, да какая детализация еще требуется? Литералы ведь преобразуются в двоичный вид. Вот и ищется вхождение последовательностей бит друг в друга.
Например, это весь поиск вхождений подстрок в строки литералов в компиляторе PL/1-KT. Детальнее уже только микрокод x86:

;══════════ ПРОВЕРКА ВХОЖДЕНИЯ СТРОКИ В СТРОКУ ═════════════════

C3DF0:CMP	B PTR [EDI]+2,28H ;НОВЫЙ ЛИТЕРАЛ ТОЖЕ СТРОКА ?
      JNZ	M3DF5		;ДРУГИЕ ТИПЫ ЛИТЕРАЛОВ НЕ СМОТРИМ
      MOV	AL,[EDI]+14	;ДЛИНА НОВОГО ЛИТЕРАЛА
      CMP	AL,0		;ЛИТЕРАЛ ПУСТАЯ СТРОКА ?
      JZ	M3DF5       ;ТАКИЕ НЕ РАССМАТРИВАЕМ

;---------------- ЦИКЛ ПО ВСЕМ СТРОКОВЫМ ЛИТЕРАЛАМ ---------------

      MOV	EBX,X03DA	;НАЧАЛО ХЭШ
      INC	EBX

M3DF1:CMP	EBX,X03D6	;ДОШЛИ ДО REPLACE ?
      JAE	M3DF5		;НЕ НАШЛИ ПОДХОДЯЩЕЙ СТРОКИ

      CMP	W PTR [EBX]+1,2800H ;ЭТО ТОЖЕ СТРОКОВЫЙ ЛИТЕРАЛ ?
      JNZ	M3DF4		;ДРУГИЕ НЕ РАССМАТРИВАЕМ
      CMP	B PTR [EBX]+0,16 ;ЭТО НЕ КОРОТКАЯ ССЫЛКА ?
      JB	M3DF4		;ССЫЛКИ НЕ РАССМАТРИВАЕМ
      MOV	AH,[EBX]+14	;ДЛИНА ОЧЕРЕДНОГО ЛИТЕРАЛА
      CMP	AL,AH		;НОВЫЙ МОЖЕТ БЫТЬ ЧАСТЬЮ ОЧЕРЕДНОГО ?
      JAE	M3DF4		;НЕТ, ОЧЕРЕДНОЙ КОРОЧЕ ИЛИ РАВЕН

;---- СРАВНИВАЕМ НОВЫЙ КАК ЧАСТЬ СТРОКИ ОЧЕРЕДНОГО ----

      PUSH  EDI,EBP
      LEA	EDX,[EBX]+14+1	;НАЧАЛО СТРОКИ ОЧЕРЕДНОГО
      MOV	EBP,EDI		;АДРЕС НОВОГО

M3DF2:LEA	ESI,[EBP]+14+1	;НАЧАЛО СТРОКИ НОВОГО
      MOV	EDI,EDX		;ТЕКУЩЕЕ МЕСТО В СТРОКЕ ОЧЕРЕДНОГО
      MOVZX	ECX,AL		;ДЛИНА НОВОГО ЛИТЕРАЛА
      REPZ	CCMPSB		;ВХОДИТ ПОДСТРОКОЙ В ТЕКУЩИЙ ?
      JNZ	@	    	;НЕТ, НЕ ВХОДИТ
      MOV	CL,[EBX]+14	;ДЛИНА ТЕКУЩЕГО
      SUB	CL,AH		;СТОЛЬКО БАЙТ ОТСТУПИТЬ ОТ НАЧАЛА
      ADD	ECX,[EBX]+6	;МЕСТО ПОДСТРОКИ В ВЫДЕЛЕННОЙ ПАМЯТИ
      MOV	[EBP]+6,ECX	;ВМЕСТО ВЫДЕЛЕНИЯ ПАМЯТИ
      POP	EBP,EDI
      MOVZX	ECX,B PTR [EDI]+14 ;ВОССТАНОВИЛИ ДЛИНУ ЛИТЕРАЛА
      STC		     	;НЕ НУЖНО ВЫДЕЛЯТЬ СОБСТВЕННУЮ ПАМЯТЬ
      RET

@:    DEC 	AH	    	;УМЕНЬШИЛИ ДЛИНУ СТРОКИ ТЕКУЩЕГО
      CMP	AL,AH		;НОВЫЙ УЖЕ ДЛИНЕЕ ?
      JA	M3DF3		;ТОГДА ОН УЖЕ НЕ МОЖЕТ БЫТЬ ПОДСТРОКОЙ
      INC	EDX	    	;ИДЕМ ПО СТРОКЕ ТЕКУЩЕГО ДАЛЬШЕ
      JMPS	M3DF2		;ПРОДОЛЖАЕМ ИСКАТЬ ПОДСТРОКУ

M3DF3:POP	EBP,EDI

;---- ПЕРЕХОД К СЛЕДУЮЩЕМУ ЭЛЕМЕНТУ ХЭШ ----

M3DF4:MOVZX	ESI,B PTR [EBX]
      OR	ESI,ESI
      JJZ	C046A
      ADD	EBX,ESI
      JMPS	M3DF1	

M3DF5:CLC		    	;НУЖНО ВЫДЕЛЯТЬ СОБСТВЕННУЮ ПАМЯТЬ
      RET

Ирония судьбы. Из-за неудачного названия PL/M Килдэлла пригласили на совещания, думая, что он уже сделал транслятор PL/I для микропроцессора. А выяснилось, что у него нет и никогда не было такого транслятора. Наоборот, побыв на совещании он и решил делать такой транслятор. И вот через 40 лет потомок его транслятора до сих пор используется, причем в другой стране ).

Неудачное название PL/M привело к большой путанице даже в вики. PL/M - это, скорее, ассемблер. А я имею в виду "настоящий" PL/I

http://rsdn.org/forum/flame.comp/6550274.1

Думаю, больше всех виновата мамочка Гейтса, пропихивающая стартап для сыночка. Сама IBM просто бы купила Килдэла с потрохами и он бы ваял для нее прекрасные продукты.

я придерживаюсь того мнения, что если бы на заре IBM-PC они имели бы в комплекте транслятор с PL/1, а не Си, то все равно были бы созданы языки и технологии подобные существующим сейчас. Только это было бы сделано намного быстрее и с меньшими трудностями. Но Билл Гейтс и Гари Килдэлл не договорились тогда и все пошло как пошло ((

если при любом действии со строкой нужно еще искать, где там ноль, то это больше двух регистров, например, типовые действия (начало строки в rsi)

mov rdi,rsi
mov rcx,-1
mov al,0
repnz scasb
sub rdi,rsi
mov rcx,rdi

после этого длина строки в rcx

а в данном подходе нужно добавить лишь что-нибудь типа movzx ecx,cl

и строку уже можно переписывать или сравнивать.с другой строкой или склеивать и т.п.

Программа редко обращается ко всем данным равномерно. В ней вполне могут быть миллионы проверок сравнением с двумя-тремя литералами. И тогда одинаковые адреса могут стать ощутимыми для быстродействия. А волшебных команд нет. И вряд ли 12 Кбайт литералов в реальной программе можно сжать вполовину таким приемом. Но стремиться к совершенному коду, по-моему, следует всегда. Даже без гипотетического выигрыша в деньгах.

Опять сошлюсь на Деточкина: "это такая возня...".

Разумеется можно. Сделать отдельным проходом обработку литералов. Вытащить их все из исходного текста. А далее играть литералами в тетрис )). Проблема в том, что навар, скорее всего, будет небольшим. Сливки-то уже сняты. Но, как говорил еще один киногерой: "поиск ведете в верном направлении".

Information

Rating
Does not participate
Registered
Activity