Руководство по переносу приложений с Solaris на Linux на POWER

Шесть шагов для ускорения задач по переносу

Это руководство из шести шагов поможет ускорить процесс портирования приложений. Узнайте о различиях между Solaris и Linux® на POWER®, с которыми обычно приходится сталкиваться во время портирования. Также дается введение в среду разработки для Linux, работающей на системах с процессорами IBM POWER, и сравниваются параметры компилятора и компоновщика Sun с параметрами GNU GCC и собственного компилятора IBM. В завершение рассказывается об инструментах для анализа производительности и о пакетах программ для Linux на POWER. [Статья обновлена с учетом характеристик последних версий продуктов. — Ред.]

Шакарат Скавратананонд, Технический консультант, IBM

Шакарат Скавратананонд (Chakarat Skawratananond) -- технический консультант организации IBM eServer Solutions Enablement, где он помогает ISV (независимым поставщикам ПО) в реализации возможности работы их приложений для AIX или Linux на платформе IBM pSeries. Он получил степень PhD по электронике и вычислительной технике в Университете Техаса в Остине. Связаться с ним можно по адресу chakarat@us.ibm.com.



Шон Перри, старший программист, IBM

Шон Перри (Sean Perry) — старший разработчик компиляторов в группе IBM Rational в Торонто. У него почти 20-летний опыт написания компиляторов для C и C++ для всевозможных операционных систем, в том числе AIX, Linux/ppc, Solaris и zOS.



Мэтт Дэвис, технический консультант по Linux на Power, IBM

На момент публикации оригинальной статьи Мэтт Дэвис (Matt Davis) был технически консультантом по Linux в IBM Systems Solutions Enablement team. Как участник System p Linux project с момента его основания он исследовал и тестировал новые технологии для System p Linux и написал ряд статей, обобщающих его исследования, включая Journaling File Systems for Linux on POWER, Parallel Grid Computing with Linux on POWER, Open Source Alternatives to Commercial Software for Linux on POWER и Linux Solutions Catalog. Он пришел в IBM в качестве стажера, будучи студентом University of Texas в Austin, где он получил две степени. Впоследствии Мэтт покинул компанию IBM.



10.02.2011

Как правило, перенос приложений Solaris на Linux не представляет сложностей, поскольку и Solaris, и Linux построены на основе UNIX®. Для переноса часто требуется лишь перекомпиляция с незначительными изменениями некоторых параметров компилятора и компоновщика. Приложения требуют серьезных изменений только тогда, когда они зависят от особенностей системы, и, хотя и Solaris и Linux разрабатываются с учетом стандартов, иногда случаются различия в реализациях. В данной статье описываются эти различия и даются рекомендации относительно возможных решений, если отсутствует эквивалент со стороны Linux.

Статья состоит из следующих частей:

  • План переноса
  • Замечания по переносу, включая порядок байтов и проблемы переноса с 32- на 64-разрядную архитектуру
  • Среда разработки для Linux на POWER
  • Различия между Solaris и Linux
  • Инструменты для настройки производительности и для сборки пакетов программ, имеющиеся в Linux на POWER

Мы рассматриваем процесс перехода с системы Solaris, работающей на 32- или 64-разрядных архитектурах SPARC, Intel® или AMD x86, на систему Linux, работающую на архитектуре POWER. Говоря о Solaris, мы строим наше обсуждение на версиях 9 и новее. Под Linux имеются в виду дистрибутивы, доступные для серверов с процессорами IBM POWER, а именно: SUSE LINUX Enterprise Server (SLES) версии 11 и версии 10 пакет обновления 2 и Red Hat Enterprise Linux (RHEL) версия 5 обновление 2.

План переноса

Шаг 1. Подготовка

Необходимо понимать различия между исходной и целевой платформами. Например, нужно знать, отличается ли порядок байтов на исходной платформе от порядка байтов на целевой платформе. Если исходная платформа — Solaris/x86, то порядок байтов учитывать необходимо, потому что в Linux на POWER первым расположен старший байт (big-endian), а в Solaris/x86 — младший (little-endian).

Определите, все ли необходимые сторонние пакеты (например, базы данных и библиотеки классов) имеются на целевой платформе. В случае 32-разрядных приложений подумайте, нужно ли переходить на 64-разрядные. В следующем разделе Общие замечания по переносу содержится дополнительная информация о проблемах перехода с 32 на 64 разряда, связанных с порядком байтов.

Кроме того, решите, какой компилятор использовать на целевой платформе. Если для приложения важна производительность, подумайте об использовании нативного компилятора. В разделе Среда разработки для Linux на POWER дается дополнительная информация по имеющимся компиляторам для Linux на POWER.

Шаг 2. Настройка

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

Шаг 3. Сборка

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

Шаг 4: Тест и отладка во время выполнения

После того как приложение будет успешно собрано, его тестируют на ошибки при выполнении.

Шаг 5: Настройка производительности

Теперь портированная программа работает на целевой платформе. Проконтролируйте производительность, чтобы убедиться, что программа работает так, как ожидалось. Если нет — нужно оптимизировать производительность. В разделе Настройка производительности описываются средства настройки производительности, имеющиеся для Linux на POWER.

Шаг 6: Пакетирование

Вам придётся раздавать полученный код другим? Если да, то какой формат пакета вы хотите использовать? Linux предоставляет несколько способов упаковывания приложений, например, tar-архив, установочный скрипт и RPM. В разделе Пакеты ПО приведена дополнительная информация об упаковке программного обеспечения для Linux.


Общие замечания по переносу

Этот раздел поможет при принятии решения о переводе приложений с 32-разрядной архитектуры на 64-разрядную. Также здесь изложены соображения, относящиеся к приложениям, в которых нужно будет преодолеть трудности, связанные с разным порядком следования байтов. При перенесении приложений с Solaris на платформы x86 эти трудности возникнут. Разработчики, знакомые с переходом с 32-разрядной на 64-разрядную архитектуру и с другим порядком следования байтов могут пропустить этот раздел и перейти к следующему, "Среда разработки для Linux на POWER."

С 32 разрядов на 64

Осуществляя портирование программы для Linux на POWER, также можно рассмотреть возможность преобразования 32-разрядных приложений в 64-разрядные; однако 32-разрядные приложения, для которых не требуются 64-разрядные возможности, следует оставить 32-разрядными. Любые действия, связанные с переходом на 64 разряда, следует разделить на два этапа:

  • Сначала сделайте переход на целевую платформу в 32-разрядном режиме.
  • Потом, и только потом, переходите на 64-разрядный уровень.

В противном случае проблемы, возникающие из-за смены платформы, легко можно принять за проблемы, возникающие от перехода на 64 разряда. Тем не менее приложения следует по возможности переносить на 64 разряда по следующим причинам:

  • Выигрыш от размера виртуального адресного пространства, превышающего 4 ГБ.
  • Выигрыш от большего размера физической памяти (больше 4 ГБ), если есть вероятность, что пользователи развернут приложение на системе с доступной физической памятью более 4 ГБ.
  • Выигрыш от целых чисел размером 64 бита.
  • Выигрыш от того, что полноценные 64-разрядные регистры эффективнее работают с 64-разрядной арифметикой.
  • Использование файлов размером более 2 ГБ.

Приложение может оставаться 32-разрядным и при этом работать на 64-разрядном ядре Linux на POWER без каких-либо изменений. Серверы IBM под Linux на архитектуре POWER поддерживают одновременную работу 32-разрядных и 64-разрядных приложений на 64-разрядной архитектуре без какого-либо ухудшения производительности при смене режима.

При преобразовании 32-разрядных приложений в 64-разрядные могут возникнуть две основные проблемы: несоответствие типов данных и взаимодействие между приложениями, использующими разные модели данных.

В 64-разрядной среде используется модель данных, отличная от той, что используется в 32-разрядной среде. Для Linux на POWER в 32-разрядной среде используется модель ILP32 , в то время как в 64-разрядной среде используется модель LP64. Разница между этими двумя моделями заключается в размерах типов long и pointer. Поэтому, когда приложение преобразуется с ILP32 на LP64, происходят принципиальные изменения в типах данных. Типы long и integer теперь имеют разный размер, как и указатели и целые. К тому же размер таких объектов, как структуры и объединения, если в них входят типы данных pointer или long, в 64-разрядной среде — больше. Эти различия обычно приводят к возникновению других проблем:

  • Усечение данных
  • Присвоение указателей
  • Выравнивание данных
  • Совместное использование данных

В компиляторах IBM XL есть параметр -qwarn64, помогающий проверить наличие возможных проблем преобразования данных между 32- и 64-разрядными режимами.

Тема переноса приложений с 32- на 64-разрядные системы подробно рассматривается в других публикациях, поэтому здесь мы не будем подробно останавливаться на том, как справляться с этими проблемами переноса. (Дополнительную информацию можно найти в разделе "Перенос Linux-приложений на 64-разрядные системы".)

Порядок следования байтов

Поскольку в обеих архитектурах, и SPARC, и POWER, старший байт располагается первым (big-endian), при переносе приложений между этими платформами не возникает проблем, связанных с порядком байтов. Однако при переносе x86-приложений Solaris на Linux на архитектуре POWER, возможно, придется иметь дело с проблемами переносимости, связанными с порядком байтов, поскольку в архитектуре x86 младший байт располагается первым (little-endian).

С проблемами порядка следования байтов часто сталкиваются в процессе переноса приложений с одного типа архитектуры на другой. Порядок следования определяет расположение элемента данных и его отдельных байтов при их размещении и обращении к ним в памяти. Есть два типа порядка следования байтов: от старшего к младшему (big-endian) и от младшему к старшему (little-endian).

В случае процессоров с обратным порядком байтов, например, POWER, PowerPC™ и SPARC, когда машинное слово размещается в памяти, старший по значимости байт следует первым, начиная с наименьшего адреса. В случае процессоров с прямым порядком байтов, например, процессоров Intel и Alpha, первым следует наименее значащий байт.

На рисунке 1 показано, как процессоры с обратным (big-endian) и прямым (little-endian) порядком байтов размещают в памяти шестнадцатеричное число, например, 0x89ABCDEF:

Рисунок 1. Порядок следования байтов
Порядок следования байтов

Одним из источников проблем с порядком следования байтов являются неоднородные ссылки на данные. Это обычно вызывается несоответствиями типов данных в результате приведения типов элементов данных, использования объединений или использования и манипулирования полями битов. В листинге 1 демонстрируется проблема порядка байтов, вызванная неоднородной ссылкой на данные с помощью указателя:

Листинг 1. Неоднородная ссылка на данные
int main() {
        int value;
       char *p;
       p = (char*) &value;
      value = 0x89ABCDEF;
      printf("%X.%X.%X.%X\n" p[0], p[1], p[2], p[3]);
return 0;
}

Среда разработки для Linux на POWER

В этом разделе описываются основные элементы среды разработки для Linux на POWER, включая дистрибутивы, компиляторы и то, как сюда вписывается технология Java™.

Дистрибутивы Linux

Корпоративные версии Linux для процессоров POWER предлагаются двумя ведущими поставщиками — SUSE Linux и Red Hat. Оба дистрибутива пользуются большим уважением в сообществе Linux, а различия между дистрибутивами и версиями определяются главным образом временем выхода версий. У большинства разработчиков не должно возникнуть проблем с развертыванием программного обеспечения из одних и тех же исходных текстов в любом из этих дистрибутивов:

  • SLES11
    Вышедший в начале 2009 года дистрибутив Novell SUSE Linux Enterprise Server версии 11 предоставляет значительно улучшенное новое ядро, усовершенствования в виртуализации, управлении, поддержке оборудования и совместимости. Он содержит функции и обновления, предназначенные для того, чтобы справиться с критически важными рабочими нагрузками в центрах обработки данных. SUSE Linux Enterprise Server предлагает открытое, масштабируемое решение для центра обработки данных высокой производительности. Он основан на ядре 2.6.27 и содержит GCC 4.3.2, glibc 2.9, binutils 2.19.
  • SLES10 SP2
    SUSE Linux Enterprise Server версия 10, Service Pack 2 построен на ядре Linux 2.6.16 и поддерживает все корпоративные возможности Linux на POWER. Среда разработки содержит GCC 4.1.2, glibc 2.4.31 и GNU binutils 2.16.91.
  • RHEL5.3
    Red Hat® Enterprise Linux® 5.3 базируется на ядре Linux 2.6.18 и содержит GCC 4.1.2, glibc 2.5 и binutils 2.17. В дистрибутив RHEL5 включено много усовершенствований по сравнению с предыдущими версиями. Сюда входят переключаемые на лету планировщики ввода-вывода на каждую очередь, повышение производительности Ipv4/IPv6 и усовершенствования блокировок SMP-ядра для улучшения масштабируемости и производительности.
  • RHEL4.8
    Red Hat Enterprise Linux 4.8 базируется на ядре Linux 2.6.9 и содержит GCC 3.4.6, glibc 2.3.4 и binutils 2.15. Однако пакет GCC4 обновлен до версии 4.1.2. (См. в Ресурсах ссылку на сравнение возможностей RHEL3, RHEL4 и RHEL5 на поддерживаемых платформах.)

Компиляторы

В дополнение к GNU Compiler Collection Linux на POWER, как и Solaris, предлагает набор высокопроизводительных компиляторов — набор компиляторов IBM XL C/C++. Подробную информацию о его лицензировании можно найти на Web-сайте компиляторов XL C/C++ Advanced Edition for Linux (см. ссылку в Ресурсах). Здесь дается краткий обзор каждого набора компиляторов и их преимущества:

  • GCC
    В проектах, разрабатываемых для нескольких платформ, где компилятор GCC является исходным компилятором, этот компилятор часто используется для развертывания приложений Linux на POWER. Это особенно относится к приложениям, для которых производительность не является критически важной, например, небольшим утилитам. GCC также дает возможность использовать некоторые прототипы программ, которые понятны только GCC, например, макросы GCC; однако многие из этих возможностей GCC включены и в компиляторы IBM XL C/C++.
  • Advance Toolchain
    Если в проекте можно воспользоваться преимуществами новейших технологий gcc и набора toolchain, то для клиентов, которые предпочитают оставаться на компиляторе GCC, имеется пакет Advance Toolchain. При использовании SLES10 и RHEL5 Advance Toolchain предоставляет более свежую версию компилятора gcc, а также библиотеки времени выполнения, оптимизированные для Power 6. Во многих случаях приложения, скомпилированные gcc с использованием Advance Toolchain, собранной с уровнем оптимизации -O3, будут иметь производительность, близкую к компиляторам IBM C/C++ при компиляции с уровнем -O3. Преимущества компиляторов IBM состоят в дополнительных возможностях для дальнейших улучшений и оптимизаций производительности, которые в некоторых случаях могут быть довольно существенными.
  • XL C/C++
    Для систем Power имеются Linux-компиляторы IBM XL C/C++. Для RHEL5, SLES10 и SLES11 доступны компиляторы XL C/C++ версии 10.1. Для компиляции в старых дистрибутивах Linux, например, SLES 9, SLES10 sp1, RHEL5 или RHEL 4, по-прежнему имеются более ранние версии компиляторов IBM, например, XL C/C++ версии 8 и версии 9. Компиляторы XL C/C++ предлагают высокопроизводительную альтернативу GCC, а также ряд дополнительных возможностей. К счастью, компиляторы XL C/C++ создают 32- и 64-разрядные объектные файлы GNU elf, полностью совместимые с объектными файлами, создаваемыми компиляторами GCC, поскольку эти компиляторы используют те же самые GNU-библиотеки, компоновщик, ассемблер и утилиты binutils, что и GCC. Фактически функциональность, прежде предлагавшаяся исключительно компиляторами GCC, была перенесена на XL C/C++, чтобы улучшить совместимость на уровне исходных текстов, включая некоторые макросы GCC и встраиваемые функции. Однако помимо совместимости XL C/C++ обеспечивает существенно лучшую производительность.

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

    Хотя XL C/C++ для Linux на POWER не бесплатен, для разработчиков имеется 60-дневная пробная версия. Подробную информацию можно получить на сайте XL C/C++ для Linux. (См. ссылку в Ресурсах.)
  • XL Fortran
    Если вам нужен язык Фортран, для Power-систем имеется IBM XL Fortran для Linux-компиляторов. XL Fortran версии 11.1 и XL Fortran версии 12.1 доступны для RHEL5, SLES10 и SLES11. Подробную информацию можно получить на сайте XL Fortran для Linux. (См. ссылку в Ресурсах.)

Binutils

На Solaris 10 есть возможность выбрать либо использование собственных утилит для сборки либо утилит, поставляемых с GNU. В Linux на POWER GNU binutils используются для создания объектных файлов как с набором компиляторов XL C/C++, так и GCC. Они очень подробно рассматриваются на сайте GNU Binutils. (См. ссылку в Ресурсах.)

Технология Java

Технология Java дает возможность разработчикам развертывать приложения на разных платформах без перекомпиляции программ, при условии, что Java Runtime Environment (JRE) совместима с Java Developer Kit (JDK) для платформы, на которой было разработано ПО. Наиболее современные наборы для разработки на Java для Linux на POWER поддерживаются в дистрибутивах RHEL4, RHEL5 и SLES9, SLES10 и SLES11 комплектом IBM Developer Kit для Linux, Java Technology Edition версии 1.4.2, версии 5.0 и версии 6. 32- и 64-разрядные версии можно бесплатно загрузить с сайта IBM (см.Ресурсы).


Различия между Solaris и Linux

Теперь давайте рассмотрим различия между Solaris и Linux, включая системные вызовы, сигналы, типы данных, файлы Makefile, параметры компилятора и компоновщика и библиотеки поддержки потоков.

Системные вызовы и библиотечные функции

Системные вызовы — это интерфейсы, используемые пользовательскими программами для вызова функций ядра со стороны потока или процесса. Для выполнения системного вызова требуется переключение контекста в привилегированный режим ядра. Библиотечные функции являются обычными C-функциями. Они не вызывают непроизводительных издержек в связи с переключением контекста, поскольку они являются частью адресного пространства для каждого процесса, который их использует. Некоторые системные вызовы и библиотечные функции Solaris в Linux отсутствуют; в таких случаях может потребоваться реализация обертки вызова на стороне Linux.

Linux на POWER сейчас предоставляет более 300 различных системных вызовов. Список системных вызовов можно найти в /usr/include/asm-powerpc/unistd.h или /usr/include/asm/unistd.h в зависимости от используемого дистрибутива.

Вот несколько примеров несовместимостей между Solaris и Linux:

  • regexp() и regcmp(): если в Solaris используются функции regexp() и regcmp(), то в Linux их нужно заменить на regexec() и regcomp().
  • Функции интерфейса файловой системы: функции файловой системы на Solaris используют структуры vfstab и содержат vfs в имени функций, например, getvfsent. Linux предоставляет эквивалентные интерфейсы, но в функциях используются структуры fstab и в имени функций содержится fs, например, getfsent. Структура vfstab на Solaris определяется в /usr/include/sys/vfstab.h. Определение fstab на Linux находится в /usr/include/fstab.h.
  • Функции библиотеки информации об устройствах (libdevinfo): библиотека libdevinfo содержит набор интерфейсов для доступа к данным о конфигурации устройств, например, к старшему и младшему номерам устройств. Стандартная система Linux не поддерживает этого.
  • Привязка к процессорам: по умолчанию процесс в многопроцессорной системе «перескакивает» между несколькими процессорами. Явное привязывание процесса к определенным процессорам (назначение соответствия процессоров) может в некоторых случаях привести к увеличению производительности. Системные вызовы для привязки к процессорам в Solaris отличаются от вызовов в Linux. Ядро Linux 2.6 предоставляет sched_setaffinity() и sched_getaffinity() для управления привязкой к процессорам. За более подробной информацией обращайтесь к страницам документации Linux.

В таблице 1 приводится перечень системных вызовов Solaris, которые в Linux отсутствуют или отличаются именем или сигнатурой:

Таблица 1. Системные вызовы Solaris
SolarisLinuxПримечания
acl, faclнетПолучает или устанавливает список управления доступом (ACL) файла
adjtimeнетКорректирует время, чтобы обеспечить синхронизацию системных часов
auditнетДелает запись в журнале аудита
auditonнетРабота с аудитом
auditsvcнетЗаписывает журнал аудита в указанный дескриптор файла
getacct, putacct, wracctнетПолучает, помещает или записывает расширенные учетные данные
getaudit, setaudit, getaudit_addr, setaudit_addr нетПолучает или устанавливает информацию аудита процесса
getauid, setauidнетПолучает и устанавливает идентификатор пользователя для аудита
getdentsgetdents**Читает содержимое каталогов и преобразует их формат, не зависящий от файловой системы. Структура dirent различается на Linux и Solaris.
getmsg, getpmsgнетПолучает следующее сообщение из потока
getpflags, setpflagsнетПолучает или устанавливает флаги процесса
getppriv, setpprivнетПолучает или устанавливает набор привилегий
getustack, setustackнетПолучает или изменяет адрес информации о границе стека каждого подпроцесса (LWP)
issetugidнетОпределяет, работает ли данный выполняемый файл в режиме setuid или setgid
llseek_llseekПеремещает расширенный указатель записи или чтения файла
_lwp_cond_signal, _lwp_cond_broadcastнетСигнализирует о переменной условия
_lwp_cond_wait, _lwp_cond_timedwait, _lwp_cond_reltimedwaidнетОжидает переменную условия
_lwp_infoнетВозвращает информацию учета времени одного подпроцесса
_lwp_killнетПосылает сигнал в подпроцесс
_lwp_mutex_lock, _lwp_mutex_unlock, _lwp_mutex_trylockнетВзаимное исключение
_lwp_selfнетПолучает идентификатор подпроцесса
_lwp_sema_wait, _lwp_sema_trywait, _lwp_sema_init, _lwp_sema_postнетОперации с семафорами
_lwp_suspend, _lwp_continueнетПриостанавливает / возобновляет выполнение подпроцесса
memcntlнетУправление памятью
meminfoнетПредоставляет информацию о памяти
mountmount*Монтирует файловую систему. Сигнатуры этого системного вызова на Solaris и Linux различаются.
msgidsнетОбнаруживает все идентификаторы очередей сообщений
msgrcvmsgrcv*Операция приема сообщений. Linux использует тип struct msgbuf в одном из аргументов.
msgsnapнетОперация получения снимка очереди сообщений
msgsndmsgsnd*Операция отправки сообщений. Linux использует тип struct msgbuf в одном из аргументов.
ntp_adjtimeнетРегулирует параметры локальных часов
ntp_gettimeнетПолучает значения с локальных часов
open, openatopen*Открывает файл. openat() отсутствует в Linux.
pcsampleнетПрофиль времени выполнения программы
p_onlineнетВозвращает или меняет рабочий статус процессора
priocntlнетПараметры планировщика процесса
priocntlsetнетОбобщенные параметры планировщика процесса
processor_bindsched_setaffinityПривязывает подпроцессы к процессору
processor_infoнетDetermines type and status of a processor
pset_bindнетПривязывает подпроцессы к набору процессоров
pset_create, pset_destroy, pset_assignнетРаботает с наборами процессоров
pset_infoнетПолучает информацию о наборе процессоров
pset_listнетПолучает список наборов процессоров
pset_setattr, pset_getattrнетУстанавливает или получает атрибуты набора процессоров
putmsg, putpmsgнетПосылает сообщение в поток
rename, renameatrename*Изменяет имя файла. В Linux renameat() отсутствует.
resolvepathнетРазрешает все символические ссылки в указанном пути
semidsнетОбнаруживает идентификаторы всех активных семафоров
setrctl, getrctlнетУстанавливает или получает значения параметров управления ресурсами
settaskid, gettaskid, getprojidнетУстанавливает или получает идентификаторы задачи или проекта
shmidsнетОбнаруживает все идентификаторы совместно используемой памяти
sigsend, sigsendsetнетПосылает сигнал процессу или группе процессов
__sparc_utrap_installнетУстанавливает пользовательский обработчик исключений SPARC V9
fstatatнетПолучает статус файла
swapctlнетУправляет подкачкой
uadminнетАдминистративные функции
unlink, unlinkatunlink*Удаляет элемент каталога. В Linux unlinkat() отсутствует.
futimesatнетУстанавливает время доступа к файлу и его изменения. Разрешает путь относительно аргумента fildes.
waitidнетОжидает изменения состояния дочернего процесса
yieldsched_yieldУступает выполнение другому подпроцессу

Сигналы

Сигналы используются для оповещения процесса или потока об определенном событии. Linux поддерживает стандартные сигналы POSIX и сигналы POSIX для режима реального времени. Каждый сигнал имеет уникальное имя и соответствующий номер сигнала. Некоторые номера сигналов зависят от архитектуры. Например, номер сигнала SIGSTOP в Solaris равен 23, а в Linux на POWER — 19. Определения номеров сигналов в Linux находятся в файле /usr/include/bits/signum.

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

  • Terminate: Стандартное действие — завершение процесса.
  • Ignore: Стандартное действие — игнорирование сигнала.
  • Core: Стандартное действие — завершение процесса и вывод дампа ядра в файл (core).
  • Stop: Стандартное действие — остановка процесса.

Полный список сигналов Linux, в том числе краткое описание каждого и стандартное поведение при получении сигнала, можно получить в man-документации по signal в разделе 7 с помощью команды # man 7 signal. Имейте в виду, что для Linux:

  • SIGABRT и SIGIOT идентичны.
  • SIGCLD и SIGCHLD идентичны.
  • SIGPOLL и SIGIO идентичны.
  • Стандартное действие для SIGPWR в Linux — завершение процесса, а в Solaris — игнорирование.

В таблице 2 приводятся сигналы, поддерживаемые Solaris, но не поддерживаемые Linux на POWER:

Таблица 2. Сигналы, поддерживаемые Solaris
НазваниеСтандартное действиеОписание
SIGEMTcoreЛовушка эмулятора
SIGWAITINGignoreПараллельный сигнал, используемый библиотекой потоков
SIGLWPignoreСигнал между подпроцессами, используемый библиотекой потоков
SIGFREEZEignoreПриостановка в контрольной точке
SIGTHAWignoreВозобновление с контрольной точки
SIGCANCELignoreСигнал отмены, используемый библиотекой потоков
SIGLOSTignoreРесурс потерян (но поддерживается в Linux, работающем на SPARC)
SIGXRESignoreПревышены параметры ресурса

sigset_t определен по-разному на Solaris и на Linux. На Linux он определяется в /usr/include/bits/sigset.h таким образом:

Листинг 2. Как sigset_t определен в Linux
# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long
int)))
typedef struct
   {
       unsigned long int __val[_SIGSET_NWORDS];
   } __sigset_t;
#endif

В Solaris он определяется в /usr/include/sys/signal.h таким образом:

Листинг 3. Как sigset_t определен в Solaris
typedef struct  {                                     /* signal set type */
             unsigned int       __sigbits[4];
} sigset_t;

Базовый тип данных и выравнивание

В системе есть два различных класса типов данных: базовые типы данных и производные типы данных.

Базовые типы данных — это все типы данных, определенные языком C и C++. В таблице 3 сравниваются базовые типы данных для Linux на POWER и Solaris (значения даны в байтах):

Таблица 3. Базовые типы данных
Тип данных для:Linux на POWER, ILP32Linux на POWER, LP64Solaris, ILP32Solaris, LP64
_Bool,bool1111
char1111
wchar_t2444
short2222
int4444
float4444
long4848
pointer4848
long long8888
double8888
long double16*16*1616

*Стандартный размер long double в Linux на POWER равен 128 битам, начиная с Red Hat Enterprise Linux 5 (RHEL5) и SUSE Linux Enterprise Server 10 (SLES10). До RHEL5 или SLES10 он может быть увеличен до 128 бит, если использовать параметр компиляции -qldbl128 в компиляторах XL.

При переносе приложений между платформами или между 32-разрядными и 64-разрядными режимами нужно учитывать различия между настройками выравнивания, имеющимися в различных системах, чтобы избежать возможного снижения производительности и повреждения данных. В случае компилятора IBM XL C/C++, каждый тип данных внутри агрегатов (структуры и объединения в C/C++ и классы C++) будет выравниваться по границам байтов в соответствии с правилами linuxppc или bit-packed (с использованием параметра -qalign), где linuxppc используется по умолчанию. linuxppc использует правила выравнивания GNU C/C++ для сохранения бинарной совместимости с объектными файлами GNU C/C++.

В таблице 4 приводятся величины выравнивания для правил linuxppc и bit-packed:

Таблица 4. Значения выравнивания
Тип данныхlinuxppcbit-packed
_Bool,bool11
char11
wchar_t (32-bit)21
wchar_t (64-bit)41
int41
short21
long (32-bit)41
long (64-bit)81
long long81
float41
double81
long double161

На платформах SPARC обычно требуется выравнивание данных по равному размеру данных: двухбайтовые типы должны быть на двухбайтовой границе, а четырехбайтовые должны быть на четырехбайтовой границе. Поэтому при осуществлении переноса с Solaris на Linux нужно уделять особое внимание типам данных, имеющим разные размеры на Solaris и на Linux.

Типы данных, зависящие от системы

Выводимый тип данных — это производная или структура существующих базовых типов или других производных типов. Полученные из системы типы данных могут иметь разный размер в байтах в зависимости от используемой модели данных (32- или 64-разрядная) и аппаратных платформ. В таблице 5 приведены некоторые из производных типов данных на Linux, отличающиеся от типов на Solaris:

Таблица 5. Производные типы данных
Тип данных для:Solaris ILP32Solaris LP64Linux на POWER ILP32Linux на POWER LP64
gid_tlongintunsigned intunsigned int
mode_tunsigned longunsigned intunsigned intunsigned int
pid_tlongintintint
uid_tlongintunsigned intunsigned int
wint_tlongintunsigned intunsigned int

Сравнение GNU Make и Solaris Make

Если на исходной платформе используется Solaris Make, то нужно внести изменения в файл сборки, чтобы использовать GNU Make на Linux. Подробную информацию о различиях между Solaris Make и GNU Make можно получить в главе 6 книги "Руководство по переносу для AIX 5L."

Параметры компилятора

В таблице 6 приводится список широко используемых параметров компилятора для компилятора Sun Studio и эквивалентные параметры для компиляторов GNU Compiler Collection и IBM's XL:

Таблица 6. Параметры компилятора
Параметр Sun StudioПараметр GNU GCCПараметр XL C/C++Описание
-#-v-vДает указание компилятору сообщать информацию о продвижении компиляции.
-###-###-#Трассирует компиляцию, ничего не запуская.
-dn-static-qstaticlinkУказывает статическое связывание.
-dy(Default)(Default)Указывает динамическое связывание.
-G-shared-qmkshrobjСоздает разделяемый объект, а не динамически связанный выполняемый файл.
-xmemalign-malign-natural,
-malign-power
-qalignУказывает выравнивание с максимальным расходованием памяти и что должно происходить при доступе к невыровненным данным.
-xO1, -xO2, -xO3, -xO4,-xO5-O, -O2, -O3-O,-O2,-O3,-O4,-O5 Оптимизирует код в соответствии с выбранными уровнями оптимизации во время компиляции.
-KPIC-fPIC-qpic=largeСоздает позиционно-независимый код для использования в разделяемых библиотеках (большая модель).
-Kpic-fpic-qpic=smallСоздает позиционно-независимый код для использования в разделяемых библиотеках (небольшая модель).
-mt-pthread Use _r invocation modeКомпиляция и связывание для многопоточной программы.
-R dirlist-Wl, -rpath, dirlist-Wl, -rpath, dirlistВстраивает путь поиска динамической библиотеки в выполняемый файл.
-xarch-mcpu, -march-qarch, -qtuneУказывает набор команд целевой архитектуры.

Компиляторы XL C/C++ поддерживают подмножество параметров компиляторов GNU для облегчения переноса приложений, разработанных с использованием компиляторов gcc и g++. Эта поддержка включается, когда используется вызов gxlc или gxlc++ и параметры компилятора GNU. В этих командах используется текстовый конфигурационный файл, определяющий соответствия параметров GNU-в-XL C/C++ и параметры по умолчанию. Этот конфигурационный файл можно изменять в соответствии со своими нуждами. Дополнительную информацию о gxlc и gxlc++ смотрите в руководстве к компилятору XL.

Потоки Solaris и библиотека NPTL

Теперь давайте посмотрим, с какими проблемами можно столкнуться при переносе многопоточных приложений с Solaris на Linux.

Solaris поддерживает две реализации потоков: потоки Solaris и потоки POSIX (pthreads). Несколько функций, реализованных в API потоков Solaris, не выполняются API pthreads, и наоборот. В совпадающих функциях аргументы могут не совпадать. Следующие возможности поддерживаются исключительно потоковым API в Solaris:

  • Способность создавать потоки-демоны. Потоки-демоны на влияют на статус выхода процесса. Процесс может завершить выполнение либо путем вызова exit(), либо если все потоки-недемоны процесса сделают вызов thr_exit().
  • Способность приостанавливать или продолжать выполнение потока с помощью thr_suspend() и thr_continue(). Имейте в виду, что thr_suspend() приостанавливает целевой поток независимо от блокировок, которые этот поток, возможно, удерживает. Если приостанавливающий поток вызывает функцию, которой требуется блокировка, удерживаемая приостановленным целевым потоком, то происходит взаимная блокировка.
  • Способность позволить потоку ожидать завершения любого присоединенного потока в процессе. Это достигается, когда первый аргумент thr_join() установлен в 0. Если установить первый аргумент pthread_join() равным 0, программа будет завершена с ошибкой сегментации.

В таблице 7 сравниваются ключевые функции для работы с потоками Solaris с функциями pthreads. По поводу других функций для работы с потоками Solaris обращайтесь к "Руководству по переносу многопоточных приложений" фирмы Sun (см. Ресурсы).

Таблица 7. Функции для работы с потоками и функции pthreads
Потоковое API SolarisПотоковое API Linux POSIXОписание
thr_create()pthread_create()Создает новый поток.
thr_exit()pthread_exit()Завершает выполнение вызывающего потока.
thr_join()pthread_join()Приостанавливает вызывающий поток, пока целевой поток не завершится.
thr_kill()pthread_kill()Посылает сигнал в другой поток.
thr_self()pthread_self()Возвращает идентификатор потока вызывающего процесса.
thr_yield()sched_yield()Заставляет текущий поток уступить выполнение другому потоку.
thr_getprio()pthread_getschedparam()Получает параметры приоритета потока.
thr_setprio()pthread_setschedparam()Изменяет параметры приоритета потока.
thr_getspecific()pthread_getspecific()Возвращает привязанное к ключу значение, имеющее отношение к потоку.
thr_setspecific()pthread_setspecific()Привязывает к ключу новое значение, имеющее отношение к потоку.
thr_getconcurrency()pthread_getconcurrency()Получает уровень параллелизма потока.
thr_setconcurrency()pthread_setconcurrency()Устанавливает уровень параллелизма потока.
thr_sigsetmask()pthread_sigmask()Изменяет или проверяет маску сигналов вызывающего потока.
thr_keycreate()pthread_key_create()Создает ключ, который размещает данные для потока.
нетpthread_key_delete()Удаляет ключ, которые размещает данные для потока.
thr_suspend()нетПриостанавливает выполнение указанного потока.
thr_continue()нетВозобновляет выполнение приостановленного потока.
fork1()fork()Обычное ветвление.
forkall()нетКопирует все ветвления.

Поведение fork() в Solaris 9 и более ранних версиях отличается от поведения fork() в потоках POSIX. В потоках POSIX fork() создает новый процесс, копируя все адресное пространство в процесс-потомок; однако он копирует только вызывающий поток в процесс-потомок. API потоков в Solaris также предоставляет семантику копирования всех потоков forkall(). Эта функция копирует адресное пространство и все потоки в процесс-потомок. Эта особенность не поддерживается стандартом потоков POSIX.

Некоторые функции потоков POSIX, реализованные в Solaris, отсутствуют в Linux, и наоборот. В таблице 8 перечисляются эти функции:

Таблица 8. Функции потоков POSIX
ФункцииSolarisLinux
pthread_cond_reltimedwait_npданет
pthread_mutexattr_getrobust_npданет
pthread_mutexattr_setrobust_npданет
pthread_mutex_consistent_npданет
pthread_mutex_reltimedlock_npданет
pthread_rwlock_reltimedrdlock_npданет
pthread_rwlock_reltimedwrlock_npданет
pthread_attr_getaffinity_npнетда
pthread_attr_setaffinity_npнетда
pthread_cleanup_pop_restore_npнетда
pthread_cleanup_push_defer_npнетда
pthread_getattr_npнетда
pthread_kill_other_threads_npнетда
pthread_rwlockattr_getkind_npнетда
pthread_rwlockattr_setkind_npнетда
pthread_timedjoin_npнетда
pthread_tryjoin_npнетда

Библиотека потоков Linux во всех версиях ядра Linux старше 2.6 называется LinuxThreads. Эта библиотека поддерживалась библиотекой GNU C с glibc 2.0 и в значительной степени совместима с POSIX. Начиная с ядра 2.6, представлена новая и улучшенная библиотека потоков, называемая Native POSIX Threading Library (NPTL). Эта реализация обеспечивает значительное повышение производительности по сравнению с LinuxThreads. К тому же NPTL намного более совместима с требованиями POSIX, чем был пакет LinuxThreads; однако одно лишь использование ядра 2.6 не означает, что используется и NPTL. Введите следующую команду, чтобы увидеть, какой реализацией POSIX вы пользуетесь:

$ getconf GNU_LIBPTHREAD_VERSION

NPTL реализует поточную модель «один к одному», где имеется соотношение один к одному между потоками в пространстве пользователя и потоками ядра. NPTL также реализует межпроцессные примитивы синхронизации POSIX. В частности, теперь поддерживается параметр потока PTHREAD_PROCESS_SHARED. По умолчанию, каждый поток создается с атрибутом detachstate, равным PTHREAD_CREATE_JOINABLE, алгоритмом планировщика SCHED_OTHER и без стека, предоставляемого пользователем.

Если ваши приложения в Solaris использует API потоков POSIX, тогда перенос их в Linux будет несложным. Имейте в виду, что даже при использовании GCC, Solaris не поддерживает NPTL. В таблице 9 приведены стандартные значения атрибутов для потоков POSIX на Linux:

Таблица 9. Стандартные значения атрибутов потоков POSIX на Linux
АтрибутСтандартные значения
scopePTHREAD_SCOPE_SYSTEM
detachstatePTHREAD_CREATE_JOINABLE
schedparam0
inhiritschedPTHREAD_EXPLICIT_SCHED
schedpolicySCHED_OTHER

Хотя при переходе с ядра 2.4 на 2.6 многим приложениям не понадобится перекомпиляция, добавление NPTL может потребовать небольших изменений в многопоточных приложениях. Инструкции по переводу приложений с использования LinuxThreads на NPTL выходят за рамки этой статьи. Дополнительную информацию можно найти в статье на LinuxDevices.com "Миграция на ядро Linux 2.6" (Ресурсы).


Настройка производительности

Как только программа перенесена и успешно запущена в Linux, выполните проверку и настройку производительности, чтобы убедиться, что перенесенная программа работает на целевой платформе хорошо. Этот раздел содержит перечень инструментов, имеющихся для Linux на POWER, которые помогут выполнить проверку.

Общие инструменты для проверки и настройки производительности

Две распространенных утилиты —пакет sysstat и nmon— могут облегчить проверку и настройку производительности:

  • Пакет sysstat содержит общие расширенные средства для базового контроля производительности, в том числе такие утилиты, как mpstat, iostat и sar.
  • nmon объединяет различные классические средства системного контроля в одном универсальном инструменте сбора данных. Имеется ряд действительно удобных дополнений для последующей обработки, предназначенных для обобщения информации, построения графиков и объединения информации воедино.

OProfile

OProfile — это общесистемный профилировщик для Linux, опирающийся на аппаратные события, например, непопадания в кэш или циклы процессора. Например, OProfile может помочь определить, которая из исходных процедур вызывает наибольшее число пропусков кэша. OProfile использует аппаратные счетчики производительности, предоставляемые во многих процессорах, включая IBM POWER4™, POWER5™, POWER6™ и PowerPC™ 970. Чтобы получить дополнительную информацию, посетите сайт OProfile (см. ссылку в Ресурсах).

OProfile для Linux на POWER имеется в SLES10, SLES11, RHEL5 и в Advance Toolchain. Краткий справочник по OProfile на установленной системе можно найти в /usr/share/doc/packages/oprofile.

Post-link optimization (FDPRpro)

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

На момент написания этой статьи инструмент оптимизации Post-Link Optimization поддерживается в SLES8 и более свежих версиях и в RHEL3 и и более свежих версиях. За получением дополнительной информации посетите сайт alphaWorks Post-Link Optimization для Linux на POWER (см. ссылку в Ресурсах).


Пакеты ПО

Прикладное программное обеспечение поставляется пользователям в так называемом пакете. Пакет — это набор связанных файлов (двоичные файлы, библиотеки, документация и исходные тексты) и метаданных. Метаданные используются системой управления пакетами для согласования всех частей пакета. В качестве менеджера пакетов в Solaris используется pkgadmin. RPM — это система управления пакетами, широко используемая на Linux. Для получения дополнительной информации об RPM посетите сайт www.rpm.org (см. ссылку в разделеРесурсы).

Имейте в виду, что файлы шаблонов спецификации пакетов, используемые pkgadmin в Solaris, отличаются от spec-файла, используемого в RPM; преобразование информации о пакете из шаблонных файлов в spec-файлы требует значительных усилий.


Заключение

В большинстве случаев для переноса с Solaris на Linux на POWER требуется лишь перекомпиляция или небольшие изменения в параметрах компилятора и компоновщика. Однако Solaris и Linux решены принципиально по-разному:

  • Solaris ориентирована на производительность, масштабируемость и надежность в ущерб переносимости.
  • Linux спроектирован с расчетом на переносимость и поддерживается почти на всех аппаратных платформах, имеющихся сегодня.

Современные дистрибутивы Linux строятся на основе ядра Linux 2.6, у которого по-прежнему есть преимущества, связанные с наличием значительных усовершенствований, вносимых крупными компаниями и сообществом. По сравнению с ранними версиями на основе ядра Linux 2.4, в дистрибутивах SLES10 SP2, RHEL5.2 и SLES11 значительно улучшена производительность, масштабируемость и надежность. В Linux, работающей на системах Power, приложения имеют все возможности для полноценной реализации высокой производительности, масштабируемости, виртуализации и управления.

Имейте в виду, что в Solaris имеются некоторые характерные для системы возможности, которых нет в Linux.

Благодарности

Благодарим Стива Манро (Steve Munroe), Марка Брауна (Mark Brown), Кевина Ли (Kevin Li) и Ральфа Нисслера (Ralph Nissler) за их неоценимые комментарии.

Ресурсы

Научиться

Получить продукты и технологии

  • Загрузите компилятор Advance Toolchain для Linux на POWER. (EN)
  • Получите IBM Developer Kit for Linux, Java Technology Edition: имеются J2SE 1.3.1, 1.4.2, 5.0 и Java SE 6.(EN)
  • Post-Link Optimization for Linux on POWER: утилита для настройки производительности, работающая на основе профилей времени выполнения и используемая для уменьшения времени выполнения и использования физической памяти прикладными программами уровня пользователя. (EN)
  • Посетите сайт OProfile. OProfile для Linux на POWER обычно упаковывается в пакеты rpm на носителях с SDK для RHEL и SLES. (EN)
  • Используйте в вашем следующем проекте разработки для Linux ознакомительные версии ПО IBM, которые можно скачать непосредственно с developerWorks.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=626263
ArticleTitle=Руководство по переносу приложений с Solaris на Linux на POWER
publish-date=02102011