Оптимизация программного кода. Основные возможности оптимизации кода программистом и компилятором. Оптимизация программного кода


Рефакторинг и оптимизация программного кода. — КиберПедия

Оптимизация - процесс выбора наилучшего (оптимального) варианта из множества возможных или модификация системы для улучшения её эффективности.

Истинно оптимальная система в процессе оптимизации достигается далеко не всегда. Оптимизированная система обычно является оптимальной только для одной задачи или группы пользователей. Как правило, процесс оптимизации завершается до того, как достигается полная оптимальность.

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

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

Оптимизация в основном фокусируется на одиночном или повторном времени выполнения, использовании памяти, дискового пространства, пропускной способности или некотором другом ресурсе. Это обычно требует компромиссов — один параметр оптимизируется за счёт других.

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

Для оптимизации требуется найти узкое место (англ. hotspot): критическую часть кода, которая является основным потребителем необходимого ресурса. Улучшение примерно 20 % кода иногда влечёт за собой изменение 80 % результатов. Для поиска узких мест используются специальные программы — профайлеры.

Чем больше памяти использует программа, тем быстрее она обычно выполняется.

Простейшие приёмы оптимизации:

- Инициализация объектов данных (Правильная инициализация объектов позволяет сэкономить процессорное время.)

- Программирование арифметических операций(самыми быстрыми являются операции сложения и вычитания. Более медленным является умножение, затем идёт деление)

Приоритеты оптимизации:

• интерфейсный, т.е. желательно заранее ВСЁ согласовать с другими участниками проекта, включая кому сколько процессорного времени на конкретном ПК.

• Если ПК не является современным и многопроцессорным, заведомо сильно ограничить суммарный CPU расход, можно утилитами типа slowcpu.

• согласовать и обсудить - не спеша, и каждую мелочь вплоть до того где использовать ООП, а где нет - для ускорения.

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

Рефакторинг — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы[1]. В основе рефакторинга лежит последовательность небольших эквивалентных (то есть сохраняющих поведение) преобразований.

Цель рефакторинга — сделать код программы легче для понимания.

Рефакторинг следует отличать от оптимизации производительности. Как и рефакторинг, оптимизация обычно не изменяет поведение программы, а только ускоряет ее работу. Но оптимизация часто затрудняет понимание кода, что противоположно рефакторингу[2].

Основные стимулы его проведения являются следующие задачи:

- необходимо добавить новую функцию, которая недостаточно укладывается в принятое архитектурное решение;

- необходимо исправить ошибку, причины возникновения которой сразу не ясны;

 

Сборка, внедрение и поставка ПО

Программа – это не только .exe модуль. Скорее всего он зависит от своего окружения: системные библиотеки и компоненты Windows, исполняющая среда, Dll библиотеки.

Средство создания дистрибутивов мы будем называть инсталлятор. Под словом дистрибутив понимаем распространяемые файлы программы — обычно это Setup.exe плюс, возможно, еще несколько файлов.

Bootstrapper. Эта часть программы установки запускается первой и ее задача — подготовить все необходимое для работы installation engine. В частности, в случае использования Windows Installer, bootstrapper обеспечивает установку или обновление Windows Installer до требуемой версии.

Программа установки либо использует свой собственный installation engine, либо пользуется услугами сервиса Windows Installer. Installation engine выполняет всю основную работу: взаимодействует с пользователем через GUI, создает/удаляет папки и ключи реестра, копирует файлы, регистрирует компоненты

cyberpedia.su

4.8 Оптимизация кода

4.8.1 Сущность оптимизации кода

Полученный в результате генерации объектный код может содержать лишние команды и данные. Это снижает эффективность выполнения результирующей программы. В принципе компилятор может завершить на этом генерацию кодарацию кода, поскольку результирующая программа построена и она является эквивалентной по смыслу (семантике) программе на входном языке. Однако эф­фективность результирующей программы важна для ее разработчика, поэтому большинство современных компиляторов выполняют еще один этап компиля­ции - оптимизацию результирующей программы (или просто «оптимизацию»), чтобы повысить ее эффективность насколько это возможно.

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

Оптимизация программы — это обработка, связанная с переупорядочиванием иизменением операций в компилируемой программе с целью получения более эф­фективной результирующей объектной программы. Оптимизация выполняется на этапах подготовки к генерации и непосредственно при генерации объектногокода.

4.8.2 Критерии эффективности результирующей программы

В качестве показателей эффективности результирующей программы можно ис­пользовать два критерия: объем памяти, необходимый для выполнения результи­рующей программы (для хранения всех ее данных и кода), и скорость выполнения (быстродействие) программы. Далеко не всегда удается выполнить оптимизацию так, чтобы удовлетворить обоим этим критериям. Зачастую сокращение необхо­димого программе объема данных ведет к уменьшению ее быстродействия, и на­оборот. Поэтому для оптимизации обычно выбирается либо один из упомянутых критериев, либо некий комплексный критерий, основанный на них. Выбор кри­терия оптимизации обычно выполняет непосредственно пользователь в настрой­ках компилятора.

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

Чтобы оценить эффективность результирующей программы, полученной с по­мощью того или иного компилятора, часто прибегают к сравнению ее с эквива­лентной программой (программой, реализующей тот же алгоритм), полученной из исходной программы, написанной на языке ассемблера. Лучшие оптимизи­рующие компиляторы могут получать результирующие объектные программы из сложных исходных программ, написанных на языках высокого уровня, почти не уступающие по качеству программам на языке ассемблера. Обычно соотноше­ние эффективности программ, построенных с помощью компиляторов с языков высокого уровня, к эффективности программ, построенных с помощью ассемб­лера, составляет 1,1-1,3. То есть объектная программа, построенная с помощью компилятора с языка высокого уровня, обычно содержит на 10-30 % больше ко­манд, чем эквивалентная ей объектная программа, построенная с помощью ас­семблера, а также выполняется на 10-30 % медленнее.

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

studfiles.net

Оптимизация программного кода. основные возможности оптимизации кода программистом и компилятором — Информатика, информационные технологии

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

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

Оптимизация программистом.

1). Расширить структуру данных добавлением дополнительной информации или изменить представление данных в этой структуре. 2). Вычисление результатов заранее и их хранение, для последующего использования. 3). Применение упаковки данных.

4). Внутренний цикл должен содержать min возможное количество проверок, а лучше всего только одну. 5).

Удаление безусловных переходов. 6). Логические проверки должны быть расположены так, чтобы более быстрые условия, которые чаще оказываются правильными, стояли перед более медленными условиями, которые реже оказываются правильными.7).Логическая функция на небольшом множестве исходных значений может быть заменена таблицей, представляющей это множество.8).Удаление одинаковых выражений.

9).Если два и более одинаковых выражения часто вычисляются подряд, их следует вынести в подпрограмму. 10). Изменение типов данных может оказаться эффективным способом сокращения кода и повышения его быстродействия.

11). Переписывание кода на низкоуровневом языке. При низком быстродействии код следует переписать на языке низкого уровня. Если вы пишите на С++, языком низкого уровня может быть Assembler.

Переписывание кода на низкоуровневом языке обычно положительно влияет на быстродействие кода.

Оптимизация компилятором.

Методы оптимизации кода могут применяться на разных уровнях синтаксических конструкций: 1). на уровне оператора — большинство компиляторов выполняют некоторую оптимизацию на этом уровне. 2). на уровне блока – оптимизирующий компилятор выделяет операционную структуру программе путем конструирования ориентированного потокового графа программы, в кот каждая вершина представляет основной блок, а связи м/у вершинами представляют потоки управления.

Большинство компиляторов производят оптимизацию на уровне блока. 3). на уровне цикла. 4). на уровне программы — наиболее сложный уровень оптимизации.

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

42. Оформление программ: основные пункты.

1) Описание реализации (язык, среда программирования, тестирования, предполагаемого исполнения):

2) Обращение к подпрограмме (число, тип и порядок передачи входных параметров): способ передачи (по ссылке или по значению).

3) Описание возвращаемых параметров:

4) Описание исключительных ситуаций и реакция программы на них.

5) Описание сообщений программы, если они есть.

6) Краткое описание алгоритма:

7) Привести автора программы и время написания программы.

8) Описать все входные и выходные файлы и краткое их содержимое.

9) Привести структуры записи всех файлов:

Рандомно подобранные статьи с сайта:

Оптимизация кода #2. Проверка на простоту

Похожие статьи:

kna-school4.ru

Оптимизация программного кода. Основные возможности оптимизации кода программистом и компилятором

Оптимизация программного кода называют изменение корректного кода, направленное на повышение его эффективности. «Оптимизация» подразумевает внесение небольших изменений, затрагивающих один класс, один метод, а чаще всего – несколько строк кода. Крупномасштабные изменения проекта или другие высокоуровневые способы повышения производительности оптимизацией не считаются. Это не самый эффективный способ повышения производительности. Улучшение архитектуры программы, перепроектирование классов и выбор более эффективного алгоритма - приводят к более впечатляющим результатам. Кроме того, оптимизация кода не самый легкий способ повысить производительность: легче купить новое оборудование или компилятор с улучшенным модулем оптимизации. Наконец, это не самый дешевый способ повысить производительность: на оптимизацию кода вручную изначально уходит много времени, а потом оптимизированный код труднее сопровождать.

Оптимизация программистом.

1). Расширить структуру данных добавлением дополнительной информации или изменить представление данных в этой структуре. 2). Вычисление результатов заранее и их хранение, для последующего использования. 3). Применение упаковки данных. 4). Внутренний цикл должен содержать min воз­можное количество проверок, а лучше всего только одну. 5). Удаление безусловных переходов. 6). Логические проверки должны быть располо­жены так, чтобы более быстрые условия, которые чаще оказываются пра­вильными, стояли перед более медленными условиями, которые реже оказываются правильными.7).Логическая функция на небольшом множестве исходных значений может быть заменена таблицей, представляющей это множество.8).Удаление одинаковых выражений. 9).Если два и более одинаковых выражения часто вычисляются подряд, их следует вынести в подпрограмму. 10). Изменение типов данных может оказаться эффективным способом сокращения кода и повышения его быстродействия. 11). Переписывание кода на низкоуровневом языке. При низком быстродействии код следует переписать на языке низкого уровня. Если вы пишите на С++, языком низкого уровня может быть Assembler. Переписывание кода на низкоуровневом языке обычно положительно влияет на быстродействие кода.

Оптимизация компилятором.

Методы оптимизации кода могут применяться на разных уровнях синтаксических конструкций: 1). на уровне оператора - большинство компиляторов выполняют некоторую оптимизацию на этом уровне. 2). на уровне блока – оптимизирующий компилятор выделяет операционную структуру программе путем конструирования ориентированного потокового графа программы, в кот каждая вершина представляет основной блок, а связи м/у вершинами представляют потоки управления. Большинство компиляторов производят оптимизацию на уровне блока. 3). на уровне цикла. 4). на уровне программы - наиболее сложный уровень оптимизации.

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

42. Оформление программ: основные пункты.

1) Описание реализации (язык, среда программирования, тестирования, предполагаемого исполнения):

· размеры в байтах, операциях, строках;

· размеры необходимой памяти под данные;

· требуемые технические ресурсы.

2) Обращение к подпрограмме (число, тип и порядок передачи входных параметров): способ передачи (по ссылке или по значению).

3) Описание возвращаемых параметров:

· параметр, который возвращает сама функция;

· описание входных параметров, которые функция изменяет.

4) Описание исключительных ситуаций и реакция программы на них.

5) Описание сообщений программы, если они есть.

6) Краткое описание алгоритма:

· если известен автор, то указать его имя;

· если имеет название, то указать его;

· назвать источник или где приведен текст программы, откуда был взят алгоритм;

· можно привести блок-схему.

7) Привести автора программы и время написания программы.

8) Описать все входные и выходные файлы и краткое их содержимое.

9) Привести структуры записи всех файлов:

· разбивка по полям записи;

· для каждого поля указать тип, длину смещения от начала записи.

student2.ru

Оптимизация программного кода. Основные возможности оптимизации кода программистом и компилятором

Оптимизация программного кода называют изменение корректного кода, направленное на повышение его эффективности. «Оптимизация» подразумевает внесение небольших изменений, затрагивающих один класс, один метод, а чаще всего – несколько строк кода. Крупномасштабные изменения проекта или другие высокоуровневые способы повышения производительности оптимизацией не считаются. Это не самый эффективный способ повышения производительности. Улучшение архитектуры программы, перепроектирование классов и выбор более эффективного алгоритма - приводят к более впечатляющим результатам. Кроме того, оптимизация кода не самый легкий способ повысить производительность: легче купить новое оборудование или компилятор с улучшенным модулем оптимизации. Наконец, это не самый дешевый способ повысить производительность: на оптимизацию кода вручную изначально уходит много времени, а потом оптимизированный код труднее сопровождать.

Оптимизация программистом.

1). Расширить структуру данных добавлением дополнительной информации или изменить представление данных в этой структуре. 2). Вычисление результатов заранее и их хранение, для последующего использования. 3). Применение упаковки данных. 4). Внутренний цикл должен содержать min воз­можное количество проверок, а лучше всего только одну. 5). Удаление безусловных переходов. 6). Логические проверки должны быть располо­жены так, чтобы более быстрые условия, которые чаще оказываются пра­вильными, стояли перед более медленными условиями, которые реже оказываются правильными.7).Логическая функция на небольшом множестве исходных значений может быть заменена таблицей, представляющей это множество.8).Удаление одинаковых выражений. 9).Если два и более одинаковых выражения часто вычисляются подряд, их следует вынести в подпрограмму. 10). Изменение типов данных может оказаться эффективным способом сокращения кода и повышения его быстродействия. 11). Переписывание кода на низкоуровневом языке. При низком быстродействии код следует переписать на языке низкого уровня. Если вы пишите на С++, языком низкого уровня может быть Assembler. Переписывание кода на низкоуровневом языке обычно положительно влияет на быстродействие кода.

Оптимизация компилятором.

Методы оптимизации кода могут применяться на разных уровнях синтаксических конструкций: 1). на уровне оператора - большинство компиляторов выполняют некоторую оптимизацию на этом уровне. 2). на уровне блока – оптимизирующий компилятор выделяет операционную структуру программе путем конструирования ориентированного потокового графа программы, в кот каждая вершина представляет основной блок, а связи м/у вершинами представляют потоки управления. Большинство компиляторов производят оптимизацию на уровне блока. 3). на уровне цикла. 4). на уровне программы - наиболее сложный уровень оптимизации.

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

 

42. Оформление программ: основные пункты.

1) Описание реализации (язык, среда программирования, тестирования, предполагаемого исполнения):

· размеры в байтах, операциях, строках;

· размеры необходимой памяти под данные;

· требуемые технические ресурсы.

2) Обращение к подпрограмме (число, тип и порядок передачи входных параметров): способ передачи (по ссылке или по значению).

3) Описание возвращаемых параметров:

· параметр, который возвращает сама функция;

· описание входных параметров, которые функция изменяет.

4) Описание исключительных ситуаций и реакция программы на них.

5) Описание сообщений программы, если они есть.

6) Краткое описание алгоритма:

· если известен автор, то указать его имя;

· если имеет название, то указать его;

· назвать источник или где приведен текст программы, откуда был взят алгоритм;

· можно привести блок-схему.

7) Привести автора программы и время написания программы.

8) Описать все входные и выходные файлы и краткое их содержимое.

9) Привести структуры записи всех файлов:

· разбивка по полям записи;

· для каждого поля указать тип, длину смещения от начала записи.

 

4-i-5.ru

Оптимизация программного кода. Основные возможности оптимизации кода программистом и компилятором

Оптимизация программного кода называют изменение корректного кода, направленное на повышение его эффективности. «Оптимизация» подразумевает внесение небольших изменений, затрагивающих один класс, один метод, а чаще всего – несколько строк кода. Крупномасштабные изменения проекта или другие высокоуровневые способы повышения производительности оптимизацией не считаются. Это не самый эффективный способ повышения производительности. Улучшение архитектуры программы, перепроектирование классов и выбор более эффективного алгоритма - приводят к более впечатляющим результатам. Кроме того, оптимизация кода не самый легкий способ повысить производительность: легче купить новое оборудование или компилятор с улучшенным модулем оптимизации. Наконец, это не самый дешевый способ повысить производительность: на оптимизацию кода вручную изначально уходит много времени, а потом оптимизированный код труднее сопровождать.

Оптимизация программистом.

1).Расширить структуру данных добавлением дополнительной информации или изменить представление данных в этой структуре. 2).Вычисление результатов заранее и их хранение, для последующего использования. 3) . Применение упаковки данных. 4) . Внутренний цикл должен содержать min воз­можное количество проверок, а лучше всего только одну. 5) . Удаление безусловных переходов. 6) . Логические проверки должны быть располо­жены так, чтобы более быстрые условия, которые чаще оказываются пра­вильными, стояли перед более медленными условиями, которые реже оказываются правильными.7). Логическая функция на небольшом множестве исходных значений может быть заменена таблицей, представляющей это множество.8). Удаление одинаковых выражений. 9). Если два и более одинаковых выражения часто вычисляются подряд, их следует вынести в подпрограмму. 10) . Изменение типов данных может оказаться эффективным способом сокращения кода и повышения его быстродействия. 11) . Переписывание кода на низкоуровневом языке. При низком быстродействии код следует переписать на языке низкого уровня. Если вы пишите на С++, языком низкого уровня может быть Assembler. Переписывание кода на низкоуровневом языке обычно положительно влияет на быстродействие кода.

Оптимизация компилятором.

Методы оптимизации кода могут применяться на разных уровнях синтаксических конструкций: 1 ). на уровне оператора - большинство компиляторов выполняют некоторую оптимизацию на этом уровне. 2 ). на уровне блока – оптимизирующий компилятор выделяет операционную структуру программе путем конструирования ориентированного потокового графа программы, в кот каждая вершина представляет основной блок, а связи м/у вершинами представляют потоки управления. Большинство компиляторов производят оптимизацию на уровне блока. 3 ). на уровне цикла. 4 ). на уровне программы - наиболее сложный уровень оптимизации.

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

42. Оформление программ: основные пункты.

1) Описание реализации (язык, среда программирования, тестирования, предполагаемого исполнения):

· размеры в байтах, операциях, строках;

· размеры необходимой памяти под данные;

· требуемые технические ресурсы.

2) Обращение к подпрограмме (число, тип и порядок передачи входных параметров): способ передачи (по ссылке или по значению).

3) Описание возвращаемых параметров:

· параметр, который возвращает сама функция;

· описание входных параметров, которые функция изменяет.

4) Описание исключительных ситуаций и реакция программы на них.

5) Описание сообщений программы, если они есть.

6) Краткое описание алгоритма:

· если известен автор, то указать его имя;

· если имеет название, то указать его;

· назвать источник или где приведен текст программы, откуда был взят алгоритм;

· можно привести блок-схему.

7) Привести автора программы и время написания программы.

8) Описать все входные и выходные файлы и краткое их содержимое.

9) Привести структуры записи всех файлов:

· разбивка по полям записи;

· для каждого поля указать тип, длину смещения от начала записи.

studlib.info

Оптимизация 64-битных программ

Аннотация

В статье рассмотрен ряд способов повышения производительности 64-битных Windows приложений.

Введение

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

1. Эффект от перехода на 64-битные системы

В 64-битной среде старые 32-битные приложения выполняются благодаря подсистеме Wow64. Эта подсистема эмулирует 32-битное окружение, за счет дополнительной прослойки между 32-битным приложением и 64-битным Windows API. Где-то это прослойка тонкая, где-то не очень. Для средней программы потери в производительности из-за наличия такой прослойки составят около 2%. Для некоторых программ это значение может быть больше. Конечно 2% это немного, но все-таки следует учитывать, что 32-битные приложения работают немного медленнее под управлением 64-битной операционной системы Windows, чем под 32-битной.

Компиляция 64-битного кода не только исключает необходимость в Wow64, но и дает дополнительный прирост производительности. Это связано с архитектурными изменениями в микропроцессоре, такими как увеличение количества регистров общего назначения. Для средней программы прирост производительности, от простой перекомпиляции программы можно ожидать в пределах 5-15%. Но здесь все опять очень сильно зависит от типа приложения и типа данных, которые она обрабатывает. Например, компания Adobe заявляет, что новый 64-битный "Photoshop CS4" на 12% быстрее его 32-битной версии.

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

В качестве примера можно привести интеграцию Альфа-Банком в свою IT-инфраструктуру платформы на базе Itanium 2. Рост инвестиционного бизнеса банка привел к тому, что система в имеющейся конфигурации перестала справляться с возрастающей нагрузкой: задержки в обслуживании пользователей временами достигали критической отметки. Анализ ситуации показал, что узким местом системы является не производительность процессоров, а ограничение 32-разрядной архитектуры в части подсистемы памяти, не позволяющей эффективно использовать больше 4 Гбайт адресного пространства сервера. Объем базы данных превышал 9 Гбайт. Использовалась она весьма интенсивно, что приводило к критической загрузке подсистемы ввода-вывода. Альфа-Банк принял решение о закупке кластера из двух четырехпроцессорных серверов на базе Itanium 2 с объемом оперативной памяти — 12 Гбайт. Это решение позволило обеспечить необходимый уровень быстродействия и отказоустойчивости системы. По словам представителей компании, внедрение серверов на основе Itanium 2 позволило ликвидировать проблемы и достигнуть значительной экономии средств [1].

2. Оптимизация программного кода

Можно говорить об оптимизации на трех уровнях: оптимизации на уровне инструкций микропроцессора, оптимизация кода на уровне языков высокого уровня и алгоритмическая оптимизация с учетом особенностей 64-битных систем. Первая оптимизация доступна при использовании таких средств разработки как ассемблер и слишком специфична, чтобы быть интересной широкому кругу читателей. Для тех, кто интересуется этой тематикой, можно порекомендовать, например, руководство компании AMD по оптимизации приложений для 64-битной архитектуры: "Software Optimization Guide for AMD64 Processors" [2]. Алгоритмическая оптимизация уникальна для каждой задачи и ее обсуждение также выходит за рамки данной статьи.

С точки зрения языков высокого уровня, таких как Си++, оптимизация под 64-битную архитектуру заключается в выборе оптимальных типов данных. Использование однородных 64-битных типов данных позволяет оптимизирующему компилятору строить более простой и эффективный код, так как отсутствует необходимость частого преобразования 32-битных и 64-битных данных между собой. В первую очередь это относится к переменным используемых в качестве счетчиков циклов, индексов массивов и для переменных хранящих различные размеры. По традиции в языках Си и Си++ для представления перечисленных объектов используются такие типы как: int, unsigned и long. В рамках 64-битных Windows систем, использующих модель данных LLP64 [3], эти типы остались 32-битными. Это приводит в ряде случаев к построению менее эффективного кода за счет дополнительных преобразований. Например, чтобы в 64-битном коде вычислить адрес элемента в массиве, 32-битный индекс должен быть вначале расширен до 64-бит.

Таблица 1. Размерность типов данных в 32-битных и 64-битных версиях операционной системы Windows.

Использование ptrdiff_t, size_t и производных от них типов позволяет оптимизировать программный код от единиц до десятков процентов. Вы можете познакомиться с примером такой оптимизации в статье "Разработка ресурсоемких приложений в среде Visual C++" [4]. Дополнительным преимуществом от использования типов ptrdiff_t и size_t является более надежный код. Использование 64-битных переменных в качестве индексов позволяет избежать переполнений, когда необходимо иметь дело с большими массивами, состоящими из нескольких миллиардов элементов.

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

3. Снижение расхода памяти

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

С увеличением потребляемой оперативной памяти часто можно мириться. Преимущество 64-битных систем как раз и заключается в том, что этой памяти много. Нет ничего отрицательного, что на 32-битной системе с 2 гигабайтами памяти программа занимала 300 Мбайт, а на 64-битной системе с 8 гигабайтами памяти программа займет 400 Мбайт. В относительных единицах мы получим, что программа на 64-битной системе занимает в 3 раза меньше доступной физической памяти. С описанным ростом потребляемой памяти нет смысла бороться. Проще добавить еще немного памяти.

Но существует и негативная сторона увеличения потребляемой памяти. Она связана с потерей производительности. Хотя 64-битный программный код работает быстрее, извлечение большего объема данных из памяти может свести на нет все преимущества и даже снизить производительность. Передача данных между памятью и микропроцессором (кэшем) не самая дешевая операция.

Предположим, мы имеем программу, которая обрабатывает большой объем текстовых данных (до 400 Мбайт). Для своих нужд программа создает массив указателей, каждый из которых указывает на очередное слово в обрабатываемом тексте. Пусть средняя длина слова равна 5 символов. Тогда программе потребуется около 80 миллионов указателей. Итого, 32-битный вариант программы потребует 400 Мбайт + (80 Мбайт * 4) = 720 Мб памяти. А вот 64-битной версии программы потребуется уже 400 Мбайт + (80 Мбайт * 8) = 1040 Мбайт памяти. Это существенный прирост, который может отрицательно сказаться на производительности программы. Причем, если нет необходимости обрабатывать тексты размером в гигабайты, никакой пользы от выбранной структуры данных нет. Простым и эффективным решением может стать использование вместо указателей, индексов типа unsigned. В этом случае размер потребляемой памяти вновь станет равной 720 Мбайт.

Бесполезно растратить существенный объем памяти можно и в связи с изменением правил выравнивания данных. Рассмотрим пример:

struct MyStruct1 { char m_c; void *m_p; int m_i; };

Размер структуры в 32-битной программе составит 12 байт, а в 64-битной - 24 байта, что весьма не экономно. Ситуацию можно исправить, изменив последовательность полей в структуре следующим образом:

struct MyStruct2 { void *m_p; int m_i; char m_c; };

Размер структуры MyStruct2 по прежнему останется равен 12 байт в 32-битной программе, а в 64-битной составит всего 16 байт. При этом с точки зрения эффективности выбоки данных структуры MyStruct1 и MyStruct2 равнозначны. Более наглядно отображение стрктур в память показано на рисунке N1.

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

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

И последнее - рост расхода стековой памяти. Размер увеличивается за счет хранения более длинных адресов возврата и выравнивания. Здесь нет смысла оптимизировать. На стеке разумный программист никогда не будет создавать объекты, размером в мегабайты. Заметим только, что если вы переносите 32-битную программу на 64-битную систему, то не забудьте изменить в настройках проекта размер выделяемого стека. Например, увеличьте его в 2 раза. По умолчанию 64-битному приложению по-прежнему, как и 32-битному, выделяется стек в размере 2 Мбайт. Этого неожиданно может оказаться недостаточным и имеет смысл подстраховаться.

Заключение

Автор надеется, что статья поможет в разработке эффективных 64-битных решений и приглашает для лучшего знакомства с 64-битными технологиями посетить сайт www.viva64.com. На этом сайте вы сможете найти множество ресурсов посвященных разработке, тестированию и оптимизации 64-битных приложений. Успехов вам в ваших 64-битных проектах!

Библиографический список

www.viva64.com


Prostoy-Site | Все права защищены © 2018 | Карта сайта