<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF106%3A%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%B2_Sun_Studio</id>
		<title>LXF106:Шаблоны в Sun Studio - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF106%3A%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%B2_Sun_Studio"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF106:%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%B2_Sun_Studio&amp;action=history"/>
		<updated>2026-05-13T07:33:20Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF106:%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%B2_Sun_Studio&amp;diff=7752&amp;oldid=prev</id>
		<title>Yaleks: Новая: {{Цикл/Sun Studio}} == Выгода от ассемблера == : ''ЧАСТЬ 1 С точки зрения обывателя, все компиляторы одинаковы – ...</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF106:%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%B2_Sun_Studio&amp;diff=7752&amp;oldid=prev"/>
				<updated>2009-05-01T18:33:21Z</updated>
		
		<summary type="html">&lt;p&gt;Новая: {{Цикл/Sun Studio}} == Выгода от ассемблера == : &amp;#039;&amp;#039;ЧАСТЬ 1 С точки зрения обывателя, все компиляторы одинаковы – ...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Цикл/Sun Studio}}&lt;br /&gt;
== Выгода от ассемблера ==&lt;br /&gt;
: ''ЧАСТЬ 1 С точки зрения обывателя, все компиляторы одинаковы – они просто переводят программы в машинный код; специалист же с ходу назовет вам десяток отличий. '''Станислав Механошин''' расскажет об одном из них – встраиваемых шаблонах.''&lt;br /&gt;
&lt;br /&gt;
Но прежде, чем вдаваться в частности, имеет смысл&lt;br /&gt;
узнать, что же такое Sun Studio. Сергей Пикалев, начальник отдела разработки ПО в Санкт-Петербургском офисе Sun Microsystems, любезно согласился ответить на все наши&lt;br /&gt;
вопросы.&lt;br /&gt;
&lt;br /&gt;
LXF: Название Sun Studio невольно наводит на мысли об интегрированной среде разработки: редактор с подсветкой синтаксиса,&lt;br /&gt;
автодополнение, рефакторинг и тому подобные вещи, упрощающие&lt;br /&gt;
жизнь программиста. А что это такое на самом деле?&lt;br /&gt;
&lt;br /&gt;
СП: На мой взгляд, в Sun Studio можно выделить три основных&lt;br /&gt;
части: компиляторы для языков C/C++ и Fortran, инструментарий&lt;br /&gt;
(отладчик, средство поиска ошибок и прочее), и собственно интегрированную среду разработки (IDE). Речь не только об удобствах – это&lt;br /&gt;
самостоятельный пакет, включающий все, что требуется для разработки приложений.&lt;br /&gt;
&lt;br /&gt;
LXF: IDE, надо полагать, базируется на NetBeans?&lt;br /&gt;
&lt;br /&gt;
СП: Конечно.&lt;br /&gt;
&lt;br /&gt;
LXF: Вы имеете в виду связку из NetBeans и подключаемого&lt;br /&gt;
модуля C/C++ Native Development (CND), или же есть какие-то&lt;br /&gt;
отличия?&lt;br /&gt;
&lt;br /&gt;
СП: Даже с установленным CND, NetBeans содержит большое количество компонентов для Java-разработки, идущих в комплекте с&lt;br /&gt;
данной IDE. В Sun Studio их нет – мы удалили некоторые специфичные для Java вещи, поскольку для программистов на C/C++ они,&lt;br /&gt;
очевидно, не нужны.&lt;br /&gt;
&lt;br /&gt;
LXF: И что, если я – фанат Emacs или Vi, то могу установить только&lt;br /&gt;
утилиты командной строки: компилятор, компоновщик, библиотеки&lt;br /&gt;
и набирать код в привычном редакторе?&lt;br /&gt;
&lt;br /&gt;
СП: Технически – да. Sun Studio имеет модульную структуру и вы&lt;br /&gt;
можете выбирать, какие пакеты установить. Однако, лицензионное&lt;br /&gt;
соглашение требует, чтобы данный продукт поставлялся единым&lt;br /&gt;
пакетом, поэтому с сайта все равно придется загрузить один архив&lt;br /&gt;
объемом около 350 МБ. Кстати, если говорить о компиляторах, то&lt;br /&gt;
они помещаются примерно в 30 МБ. Мы хотели бы изменить то, как&lt;br /&gt;
поставляется Sun Studio, и работа в этом направлении ведется, но&lt;br /&gt;
как вы понимаете, дела, в которых замешаны юридические соглашения, быстро не делаются.&lt;br /&gt;
&lt;br /&gt;
LXF: Конечно. Кстати, раз уж мы заговорили о лицензии: на каких&lt;br /&gt;
условиях распространяется Sun Studio? Известно, что Intel C&lt;br /&gt;
Compiler, например, можно получить бесплатно, но при этом нельзя&lt;br /&gt;
использовать в «коммерческих целях», а под это определение подпадает решение студентом или аспирантом научных задач или проведение практических занятий преподавателем.&lt;br /&gt;
&lt;br /&gt;
СП: 30 декабря 2005 года компания Sun Microsystems анонсировала проект Red October [Красный октябрь], в соответствии с которым&lt;br /&gt;
ряд ее продуктов, в том числе, средства разработки, в одночасье&lt;br /&gt;
стали доступными безо всякой платы: «Free for any use» [Бесплатно&lt;br /&gt;
для любых целей]. В случае Sun Studio прибыль поступает от поддержки: если некоторая организация желает, чтобы мы реализовали&lt;br /&gt;
конкретную функциональность или исправили определенную ошибку – она может заключить с нами контракт. В ином случае направление развития Sun Studio будет задаваться стратегией и приоритетами Sun Microsystems.&lt;br /&gt;
&lt;br /&gt;
LXF: Да, это весьма похоже на модель, применяемую в мире Open&lt;br /&gt;
Source. Но ведь Sun Studio – это не свободное ПО? «Free as in 'beer'»,&lt;br /&gt;
но не «Free as in 'speech'» ?&lt;br /&gt;
&lt;br /&gt;
СП: Действительно, исходные тексты Sun Studio закрыты – пока.&lt;br /&gt;
Но, как известно, наша компания имеет долгую историю публикации своих наработок и, могу вам сказать, в планах на будущее Sun&lt;br /&gt;
Studio значится на одной из первых позиций.&lt;br /&gt;
&lt;br /&gt;
LXF: Это не может не радовать – два полноценных свободно распространяемых набора компиляторов лучше, чем один. Кстати,&lt;br /&gt;
насколько мне известно, Sun Studio заявляет совместимость с GCC.&lt;br /&gt;
Это действительно так?&lt;br /&gt;
&lt;br /&gt;
СП: Да, все верно – Sun Studio совместима с GCC.&lt;br /&gt;
&lt;br /&gt;
LXF: И что, я могу взять, переопределить переменную $CC и&lt;br /&gt;
собрать с его помощью ядро Linux?&lt;br /&gt;
&lt;br /&gt;
СП: В принципе – да. Мы не выполняли всеобъемлющего тестирования, но ядро, собранное в наших лабораториях при помощи Sun&lt;br /&gt;
Studio, неплохо загружалось и работало. Правда, на практике эта&lt;br /&gt;
задача может оказаться не из легких: в исходных текстах Linux уйма&lt;br /&gt;
директив условной компиляции, и многие из них требуется подправить определенным образом; после этого все компилируется. Иными&lt;br /&gt;
словами, простого переопределения $CC пока не достаточно.&lt;br /&gt;
Помимо того, GCC и Sun Studio по-разному реализуют различные специальные возможности, скажем, выравнивание (align). GCC&lt;br /&gt;
трактует соответствующую директиву как обязательную, Sun Studio&lt;br /&gt;
же стремится следовать данному указанию до тех пор, пока оно&lt;br /&gt;
не входит в противоречие с оптимизатором кода. Если выясняется, что выравнивание мешает процедуре оптимизации – оно будет&lt;br /&gt;
нарушено. В большинстве случаев это не создает проблем, однако,&lt;br /&gt;
если программа жестко завязана на расположение байтов в памяти,&lt;br /&gt;
могут быть трудности.&lt;br /&gt;
&lt;br /&gt;
LXF: Компилятор – это, конечно, хорошо. А какие еще инструменты&lt;br /&gt;
есть в Sun Studio? Вы упомянули отладчик – с ним все более менее&lt;br /&gt;
ясно, но что такое «средство поиска ошибок»? И где профайлер?&lt;br /&gt;
&lt;br /&gt;
СП: Профайлер, разумеется, есть – просто список инструментов,&lt;br /&gt;
который я озвучил в начале беседы, никоим образом не является всеобъемлющим. А средство поиска ошибок, помимо прочего,&lt;br /&gt;
помогает справиться с такими неприятностями, как взаимные блокировки и состояния гонки. Создатели распределенных приложений&lt;br /&gt;
с ними хорошо знакомы.&lt;br /&gt;
&lt;br /&gt;
LXF: Вы имеете в виду традиционные многопоточные приложения&lt;br /&gt;
или что-то более серьезное: MPI, PVM, OpenMP?&lt;br /&gt;
&lt;br /&gt;
СП: Смотря что понимать под традиционными многопоточными&lt;br /&gt;
приложениями.&lt;br /&gt;
&lt;br /&gt;
LXF: Ну, например, использующие pthreads...&lt;br /&gt;
&lt;br /&gt;
СП: Да, pthreads поддерживается. Помимо них, поддерживаются&lt;br /&gt;
Solaris Threads, OpenMP и MPI, причем Sun Studio – пожалуй, единственная среда, в которую интегрирована возможность отладки&lt;br /&gt;
всех типов многопоточных приложений одновременно.&lt;br /&gt;
&lt;br /&gt;
LXF: Занятно. А в чем еще силен Sun Studio?&lt;br /&gt;
&lt;br /&gt;
СП: У нас очень хороший оптимизатор для процессоров AMD.&lt;br /&gt;
&lt;br /&gt;
LXF: То есть Sun Microsystems пишет компиляторы для Advanced&lt;br /&gt;
Micro Devices?&lt;br /&gt;
&lt;br /&gt;
СП: Да, Intel создает средства разработки для своих процессоров&lt;br /&gt;
самостоятельно, а AMD предпочитает передавать спецификации&lt;br /&gt;
нам. Это своего рода аутсорсинг.&lt;br /&gt;
&lt;br /&gt;
LXF: А насколько хорош оптимизатор Sun Studio? Наверное, существуют какие-нибудь тесты, сравнения...&lt;br /&gt;
&lt;br /&gt;
СП: Да, существует такая организация как Standard Performance&lt;br /&gt;
Evaluation Corporation, ее сайт расположен по адресу http://www.spec.org.&lt;br /&gt;
Она предлагает наборы тестов для измерения производительности генерируемого кода. На этом же сайте регулярно публикуются&lt;br /&gt;
результаты сравнений разных компиляторов. И Sun Studio выглядят&lt;br /&gt;
там очень неплохо.&lt;br /&gt;
&lt;br /&gt;
LXF: Ну и напоследок, хотелось бы узнать, кто использует Sun&lt;br /&gt;
Studio. GCC — де-факто стандарт в мире свободного ПО, Intel гордится, что СУБД Oracle собирается именно с помощью ICC, а какой&lt;br /&gt;
туз в рукаве припасли вы?&lt;br /&gt;
&lt;br /&gt;
СП: СУБД Oracle собирается и нашим компилятором, только для ОС&lt;br /&gt;
Solaris. Oracle вообще выбирает лучшее там, где оно действительно&lt;br /&gt;
лучшее. Я не уверен, что могу открывать секреты наших партнеров,&lt;br /&gt;
поэтому не стану называть других наших клиентов. А вот вещь, о&lt;br /&gt;
которой я могу упомянуть, говорит сама за себя. Как вы знаете, 22&lt;br /&gt;
января корпорации Sun Microsystems и Intel заключили партнерское&lt;br /&gt;
соглашение, в рамках которого Intel будет продвигать ОС Solaris&lt;br /&gt;
как критически важную операционную систему для серверов на&lt;br /&gt;
базе процессоров Intel Xeon. Так вот, в рамках этого соглашения,&lt;br /&gt;
оптимизирующие компиляторы для связки ОС Solaris – Xeon будем&lt;br /&gt;
делать именно мы, путем добавления оптимизаций и для данного&lt;br /&gt;
семейства процессоров.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Что ж, вооружившись этими сведениями, мы можем перейти к основной теме нашего материала – использованию встраиваемых шаблонов Sun Studio для повышения производительности&lt;br /&gt;
приложений.&lt;br /&gt;
&lt;br /&gt;
=== Что это такое? ===&lt;br /&gt;
Многие компиляторы языков C/C++ предоставляют разработчику&lt;br /&gt;
средства для использования встраиваемого ассемблера. В большинстве случаев это делается с использованием директив asm,&lt;br /&gt;
_asm или __asm, включаемых в тело программы. Есть такая возможность и в Sun Studio 12. Однако, в данной статье мы поговорим о другом средстве использования встраиваемого ассемблера,&lt;br /&gt;
предлагаемого компилятором Sun Studio – встраиваемых шаблонах&lt;br /&gt;
(inline templates).&lt;br /&gt;
&lt;br /&gt;
Идея встраиваемых шаблонов очень проста: вы описываете и&lt;br /&gt;
вызываете функцию, а также создаете файл с ее ассемблером. При&lt;br /&gt;
компиляции необходимо дополнительно передать компилятору имя&lt;br /&gt;
данного файла, в результате чего ассемблерный код будет встроен&lt;br /&gt;
по месту вызова. При этом требуется, чтобы код удовлетворял ABI&lt;br /&gt;
[Application Binary Interface, соглашение о низкоуровневом интерфейсе между программой и ОС, библиотеками и различными компонентами программы] вашей платформы в части соблюдения конвенции вызова функций.&lt;br /&gt;
&lt;br /&gt;
У встраиваемых шаблонов имеется ряд преимуществ перед&lt;br /&gt;
встраиваемым ассемблером, что очерчивает разумную область их&lt;br /&gt;
применимости. Перечислим некоторые из достоинств:&lt;br /&gt;
* Использование встраиваемых шаблонов, как правило, не требует изменения исходного кода программы, что в ряде случаев невозможно, а иногда – нежелательно;&lt;br /&gt;
* Там, где в исходном коде пришлось бы написать несколько препроцессорных условных выражений, с использованием встраиваемых шаблонов можно обойтись одним вызовом функции и несколькими разными файлами с ассемблером, специфичными для платформы;&lt;br /&gt;
* Шаблонами можно прозрачно заменить вызов почти любой функции (почему «почти», будет сказано ниже);&lt;br /&gt;
* Их использование не ограничено языками C и C++;&lt;br /&gt;
* Единожды написанный шаблон можно использовать повторно по имени, не копируя код напрямую или средствами препроцессора.&lt;br /&gt;
&lt;br /&gt;
Очевидно, что должны иметься и недостатки. За три года&lt;br /&gt;
использования данного средства я обнаружил два:&lt;br /&gt;
* Встраиваемые шаблоны менее стандартны, что с лихвой окупается возможностью написания функции, выполняющей тот же функционал для компиляторов, не поддерживающих такой возможности;&lt;br /&gt;
* При ABI, предусматривающем передачу аргументов через стек, параметры вызова будут переданы соответствующим образом, то есть с копированием в память. При использовании встраиваемого ассемблера этого можно избежать. Данное обстоятельство делает использование встраиваемых шаблонов наиболее эффективным на платформах с ABI, предусматривающих передачу параметров через регистры (например, x64).&lt;br /&gt;
&lt;br /&gt;
=== Как ими пользоваться? ===&lt;br /&gt;
{{Врезка&lt;br /&gt;
|Заголовок=Имена функций&lt;br /&gt;
|Содержание=Небольшое замечание по использованию идентификаторов:&lt;br /&gt;
имя функции, указанное в шаблоне, должно быть таким, каким&lt;br /&gt;
его ожидает компилятор, то есть со всеми декорациями, присущими языку программирования. Для выяснения, как именно&lt;br /&gt;
должно выглядеть имя функции, можно собрать проект без&lt;br /&gt;
шаблона и посмотреть на ошибки компоновки, содержащие&lt;br /&gt;
имена ненайденных символов, либо транслировать исходный&lt;br /&gt;
файл в ассемблер при помощи опции -S и взглянуть на реальное имя вызываемой функции. В случае C++, для упрощения&lt;br /&gt;
декорирования и совместного использования с модулями,&lt;br /&gt;
написанными на языке C, можно использовать декларации&lt;br /&gt;
вида:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;#ifdef __cplusplus&lt;br /&gt;
extern &amp;quot;C&amp;quot; {&lt;br /&gt;
#endif&lt;br /&gt;
extern void foo();&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
}&lt;br /&gt;
#endif&amp;lt;/source&amp;gt;&lt;br /&gt;
|Ширина=250px}}&lt;br /&gt;
Предположим, вам необходимо встроить ассемблер вместо такого&lt;br /&gt;
выражения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;(v &amp;lt;&amp;lt; 8) | (v &amp;gt;&amp;gt; 24)&amp;lt;/source&amp;gt;&lt;br /&gt;
Напишем простой тест:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;int test_rotate_byte_left(int v)&lt;br /&gt;
{&lt;br /&gt;
return (v &amp;lt;&amp;lt; 8) | (v &amp;gt;&amp;gt; 24);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Скомпилируем его:&lt;br /&gt;
 cc -fast -m64 -S test-rotate-expr.c&lt;br /&gt;
И посмотрим, что получилось:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;movl %edi,%eax ; загрузка аргумента&lt;br /&gt;
shll $0x8,%eax ; сдвиг влево&lt;br /&gt;
sarl $0x18,%edi ; сдвиг вправо&lt;br /&gt;
orl %edi,%eax ; побитное ИЛИ&lt;br /&gt;
ret&amp;lt;/source&amp;gt;&lt;br /&gt;
Предположим, вы хотите использовать единственную инструкцию ROL [оборот влево, при этом биты, вышедшие за границу операнда, появляются в младших позициях, – прим.ред.]. Что надо сделать? Во-первых, описать функцию и вызывать ее:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;extern int rotate_byte_left(int v);&lt;br /&gt;
int test_rotate_byte_left(int v)&lt;br /&gt;
{&lt;br /&gt;
return rotate_byte_left(v);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Во-вторых, создать в отдельном файле с расширением .il ее&lt;br /&gt;
шаблон с соблюдением требований ABI (мы пользуемся ABI x64,&lt;br /&gt;
где первый параметр передается через регистр rdi, а целочисленное возвращаемое значение ожидается в регистре rax или, в случае&lt;br /&gt;
32-битного целого, как у нас – в eax):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;.inline rotate_byte_left,0&lt;br /&gt;
roll $8,%edi&lt;br /&gt;
movl %edi,%eax&lt;br /&gt;
.end&amp;lt;/source&amp;gt;&lt;br /&gt;
В-третьих, вызвать компилятор, передав ему дополнительно имя&lt;br /&gt;
шаблона:&lt;br /&gt;
 cc -fast -m64 -S test-rotate.c rotate.il&lt;br /&gt;
Вот что получится в итоге:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;movl %edi,%eax&lt;br /&gt;
roll $010,%eax&lt;br /&gt;
ret&amp;lt;/source&amp;gt;&lt;br /&gt;
Обратите внимание, что я не писал ret в конце шаблона – этого не требуется. Однако, если вы предполагаете у функции возвращаемое значение, то его следует поместить туда, где оно&lt;br /&gt;
должно быть согласно ABI, в данном случае – в регистр eax. Если&lt;br /&gt;
бы это было значение с плавающей точкой, то оно бы возвращалось в xmm0 или на вершине стека x87 в более старой конвенции&lt;br /&gt;
вызова.&lt;br /&gt;
&lt;br /&gt;
Последний параметр после имени функции (,0) – это размер ее&lt;br /&gt;
аргументов в байтах; в настоящее время он не используется, хотя&lt;br /&gt;
должен быть указан для обратной совместимости с компилятором&lt;br /&gt;
Sun Workshop 5.0.&lt;br /&gt;
&lt;br /&gt;
Также надо отметить, что хотя в данном примере в файле&lt;br /&gt;
rotate.il определена лишь одна функция, их может быть несколько. Достаточно интересные примеры можно найти в библиотеке&lt;br /&gt;
libm.il, поставляемой с компилятором Sun Studio для различных платформ (см. файлы, расположенные в каталогах prod/lib/*&lt;br /&gt;
компилятора).&lt;br /&gt;
&lt;br /&gt;
=== Замена определения функции ===&lt;br /&gt;
В случае с заменой определения функции возникает вопрос: будет&lt;br /&gt;
ли ее конкретное использование действительно заменено шаблоном, или же будет вызвана сама функция? Очевидно, что со стопроцентной уверенностью на него может ответить дизассемблер,&lt;br /&gt;
тем не менее, я приведу правила, по которым происходит выбор&lt;br /&gt;
кода.&lt;br /&gt;
&lt;br /&gt;
Встраивание шаблона выполняется компилятором на этапе&lt;br /&gt;
трансляции модуля, то есть до компоновки всего приложения.&lt;br /&gt;
Таким образом, если функция должна быть вызвана, но для нее&lt;br /&gt;
определен шаблон – будет использован шаблон.&lt;br /&gt;
&lt;br /&gt;
Исключением являются встроенные функции, известные компилятору. Например, если вы хотите переопределить код функции strcmp(),&lt;br /&gt;
то это может не получиться. Компилятор «знает» ее, и если был&lt;br /&gt;
использован ключ -xbuiltin=%all (либо явно, либо в результате применения макроопции -fast), требующий замены встроенных функций&lt;br /&gt;
шаблонами, определенными самим компилятором, то будет выбран&lt;br /&gt;
внутренний шаблон. Здесь можно использовать опцию -xbuiltin=%none&lt;br /&gt;
для отмены действия, требуемого -fast (это нужно делать после собственно ключа -fast), либо отказаться от -xbuiltin=%all. К сожалению,&lt;br /&gt;
синтаксис этой опции на сегодня не подразумевает выбор индивидуальных функций, и можно либо включить встраивание их всех, либо&lt;br /&gt;
отключить его для указанной единицы трансляции.&lt;br /&gt;
&lt;br /&gt;
В случае использования языка Fortran переопределение встроенных функций (таких, например, как ABS) становится невозможным&lt;br /&gt;
в принципе. Здесь остается лишь использовать функцию с другим,&lt;br /&gt;
нестандартным, именем.&lt;br /&gt;
&lt;br /&gt;
То же самое происходит, если данный шаблон уже определен&lt;br /&gt;
в стандартной библиотеке libm.il, а вы используете опцию -xlibmil&lt;br /&gt;
либо явно, либо как часть -fast. Определение из libm.il имеет приоритет. В данном случае стоит скопировать требуемый libm.il и поправить определение функции, передав -xnolibmil и имя копии файла&lt;br /&gt;
с шаблонами в качестве параметров компилятора. Альтернативным&lt;br /&gt;
решением является отказ от -xlibmil и указание компилятору полного пути к соответствующей библиотеке libm.il, а также имени файла&lt;br /&gt;
с собственным шаблоном после нее. В этом случае будет использовано последнее встретившееся определение.&lt;br /&gt;
&lt;br /&gt;
=== Ограничения ===&lt;br /&gt;
Встраиваемые шаблоны по своей сути предназначены для (пере-)&lt;br /&gt;
определения кода. Не все конструкции, допустимые в ассемблере, понимаются транслятором шаблонов. Некоторые директивы,&lt;br /&gt;
такие как .align, допустимы к использованию с ограничениями на&lt;br /&gt;
оптимизацию. Некоторые, однако, не могут быть применены вовсе.&lt;br /&gt;
На самом деле, это относится к большинству псевдоопераций&lt;br /&gt;
ассемблера.&lt;br /&gt;
&lt;br /&gt;
В частности, встраиваемые шаблоны не могут использоваться&lt;br /&gt;
для определения данных. Все соответствующие директивы, такие&lt;br /&gt;
как .byte, .double и аналогичные не могут встречаться во встраиваемых шаблонах даже в том случае, если их использование допустимо в секции кода.&lt;br /&gt;
&lt;br /&gt;
Это накладывает ограничение на использование шаблонов,&lt;br /&gt;
которым требуются константы, хранящиеся в памяти. При наличии&lt;br /&gt;
необходимости в таких константах приходится применять зачастую&lt;br /&gt;
менее эффективную загрузку регистров из непосредственных операндов. Рассмотрим, например, определенную в prob/lib/amd64/libm.il функцию fabs():&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;.inline fabs,0&lt;br /&gt;
movq $0x7fffffffffffffff,%rax&lt;br /&gt;
movdq %rax,%xmm1&lt;br /&gt;
andpd %xmm1,%xmm0&lt;br /&gt;
.end&amp;lt;/source&amp;gt;&lt;br /&gt;
Можно видеть, что первые две инструкции, включая крайне&lt;br /&gt;
малоэффективную пересылку между регистром общего назначения rax и регистром xmm1, не потребовались бы, если бы было&lt;br /&gt;
возможно определить константу в памяти.&lt;br /&gt;
&lt;br /&gt;
Для обхода данного ограничения можно определить константу&lt;br /&gt;
в самой единице трансляции как глобальную переменную. В этом&lt;br /&gt;
случае шаблон выглядел бы так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;.inline fabs,0&lt;br /&gt;
andpd mask_sign,%xmm0&lt;br /&gt;
.end&amp;lt;/source&amp;gt;&lt;br /&gt;
где константа mask_sign должна быть определена в том же (и&lt;br /&gt;
в каждом) исходном файле, из которого вызывается шаблон.&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#pragma align 16 (mask_sign)&lt;br /&gt;
static const long mask_sign[2]={0x7fffffffffffffffl,0l};&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
printf(“%f\n”, fabs(-1.0));&lt;br /&gt;
printf(“%f\n”, fabs(-2.0));&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Устранение этого ограничения в будущем может существенно&lt;br /&gt;
расширить применимость встраиваемых шаблонов в Sun Studio.&lt;br /&gt;
&lt;br /&gt;
=== И в заключение ===&lt;br /&gt;
Использование встраиваемых шаблонов Sun Studio – мощный&lt;br /&gt;
инструмент, пригодный для оптимизации узких мест в программе, прозрачного переопределения действий и кода существующих&lt;br /&gt;
функций, а также для быстрого испытания экспериментальных блоков кода. С его помощью можно также использовать инструкции,&lt;br /&gt;
для которых отсутствуют как встроенные функции языка, так и возможность получить их в результате кодогенерации (такие как rtdsc,&lt;br /&gt;
rol, либо prefetch в каком-либо конкретном месте программы).&lt;br /&gt;
&lt;br /&gt;
Будучи менее стандартным, чем встраиваемый ассемблер, данный механизм, тем не менее, позволяет достичь оптимизации&lt;br /&gt;
целевого кода с большей прозрачностью, а во многих случаях, и&lt;br /&gt;
совместимостью, чем более стандартные решения. Использование&lt;br /&gt;
ассемблерного кода, оформленного практически так же, как обычная функция на языке ассемблера, делает данный подход более&lt;br /&gt;
унифицированным, позволяет меньше задумываться о взаимодействии написанного вручную ассемблера со сгенерированным автоматически. Однократное определение шаблона без использования&lt;br /&gt;
препроцессора делает вероятность ошибки меньше, а отладку и&lt;br /&gt;
сопровождение приложения – проще.&lt;br /&gt;
&lt;br /&gt;
Творческий подход к использованию встроенных шаблонов создает практически неисчерпаемые возможности их применения теми&lt;br /&gt;
разработчиками, которых не пугает перспектива написать несколько строк на ассемблере.&lt;/div&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	</feed>