Современные информационные технологии/ 3.Программное обеспечение

 

Махамбетова Г.И.

Костанайский гос. университет им.А.Байтурсынова, Казахстан

Компиляторы для программ, написанных на Си.

 

Большинство   компиляторов   Си   позволяют   пользователю указывать, какой набор команд процессора должен  использоваться  при   генерации   кода.   Хотя специализированные  инструкции конкретного процессора и могут ускорить  выполнение  программы, но  их применение может ограничить количество машин, на которых программа может работать.

        В случае, когда скорость является критическим  параметром,  "замена  вызова  функции  ее  телом"  может  помочь  в удалении  заголовков вызова функций. Некоторые компиляторы  предоставляют  возможность  заменять  операторами вызовы функций из некоторого  набора,  либо  генерировать  их  вызовы.  Набор  таких  функций содержит  некоторые общеупотребительные функции, такие как abs.  Функции из этого набора называются встроенными. Эта оптимизация полезна для внутренних циклов, которые выполняются многократно. Набор доступных встроенных функций зависит от компилятора.

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

       При   трансляции   условных   операторов   генератор  кода  компилятора  иногда  генерирует  инструкции  перехода,  которые  передают  управление  на  другие инструкции  перехода. "Сжатие цепочки  переходов"  просто  превращает   связанное   множество переходов  в единственный переход от начала цепочки переходов к конечной цели.

  Оптимизировать или нет?

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

       Оптимизация  также  может  усложнить  отладку   вследствие  генерации   кода,  который  трудно  непосредственно  связать  с  исходными операторами в программе. Оптимизация может неожиданно  ввести ошибки в  код,  сгенерированный  из  вполне  правильного текста  программы.  Ситуация, когда на переменную ссылаются как непосредственно  по  имени,  так  и  посредством   одного   или нескольких  указателей,  может затруднить работу компилятора по определению того, "жива" ли еще  переменная  и,  следовательно,  должна  оставаться  в регистре, или она "умерла" и тогда должна быть сохранена в памяти. Вынесение  инвариантного  кода  может  быть  потенциальным источником ошибок.

      В цикле       int a[10], x, y;

                          for(i = 0; i < 10; i++)

                          if( y != 0 )

                         a[i] = x / y;

оптимизирующий  компилятор  может определить, что выражение x/y есть инвариант, и  вынесет  его  за  пределы  цикла,  игнорируя  проверку  на  0  и  создавая возможность возникновения ситуации деления на 0.

      Когда компилятор выполняет  удаление  переменных  индукции цикла  он может непреднамеренно породить ситуацию переполнения, потому что он может переструктурировать вычисления,  включающие индексы  цикла [1].  В  приведенном  ранее примере, где выполняется оптимизация, используя вынесение инвариантного кода и  удаление переменных   индукции   цикла,   переменная   индукции  i  была  извлечена, в результате имеем:

             T1 = j + k;

            for(x = 0; x < T1 * v; x += T1);

      В  этом  случае,  поскольку  значения  j,  k  и  v  неизвестны, существует  возможность переполнения для выражения T1 * v. Цикл может не закончиться.

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

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

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

Литература:

1.     Б.Керниган, Д.Ритчи  Язык программирования Си- Москва -Финансы и статистика- 1992г.

2.     С.О.Бочков, Д.М.Субботин  Язык программирования Си для персонального компьютера- Москва СП-Диалог- 1996г.  

3.     Б.И.Березин, С.Б.Березин Начальный курс С и С++- Москва -Диалог-Мифи-1996г.