Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

9.4. Пример

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

Инструкция

bsrl
вычисляет местоположение старшего значащего бита в первом операнде и записывает результат (номер позиции начиная с нуля) во второй операнд. Например, следующая команда анализирует переменную number и помещает результат в переменную
position
:

asm("bsrl %1, %0" : "=r" (position) : "r" (number)};

Ей

соответствует такой фрагмент на языке С:

long i;

for (i = (number >> 1), position = 0; i != 0; ++position)

 i >>= 1;

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

result
, объявленную со спецификатором
volatile
. Это необходимо для подавления оптимизации со стороны компилятора, который удалит весь блок вычислений, если их результаты не используются или не заносятся в память.

Листинг 9.1. (bit-pos-loop.c) Нахождение позиции старшего значащего бита в цикле

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char* argv[]) {

 long max = atoi(argv[1]);

 long number;

 long i;

 unsigned position;

 volatile unsigned result;

 /* Повторяем вычисления для большого количества чисел. */

 for (number = 1; number <= max; ++number) {

/* Сдвигаем число вправо, пока результат не станет

равным нулю.

Запоминаем количество операций сдвига. */

 for (i = (number >> 1), position = 0; i != 0; ++position)

i >>= 1;

/* Позиция старшего значащего бита — это общее число

операций сдвига, кроме первой. */

result = position;

 }

 return 0;

}

Листинг 9.2. (bit-pos-asm.c) Нахождение позиции старшего значащего бита с помощью инструкции
bsrl

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char* argv[]) {

 long max = atoi(argv[1]);

 long number;

 unsigned position;

 volatile unsigned result;

 /*
Повторяем вычисления для большого количества чисел. */

 for (number = 1; number <= max; ++number) {

/* Вычисляем позицию старшего значащего бита с помощью

ассемблерной инструкции bsrl. */

asm("bsrl %1, %0" : "=r" (position) : "r" (number));

result = position;

 }

 return 0;

}

Скомпилируем обе версии программы в режиме полной оптимизации:

% cc -O2 -о bit-pos-loop bit-pos-loop.c

% cc -O2 -о bit-pos-asm bit-pos-asm.c

Теперь запустим их с помощью команды

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

% time ./bit-pos-loop 250000000

19.51user 0.00system 0:20.40elapsed 95%CPU (0avgtext+0avgdata

0maxresident)k0inputs+0outputs (73major+11minor)pagefaults 0swaps

% time ./bit-pos-asm 250000000

3.19user 0.00system 0:03.32elapsed 95%CPU (0avgtext+0avgdata

0maxresident)k0inputs+0outputs (73major+11minor)pagefaults 0swaps

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

9.5. Вопросы оптимизации

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

asm
не используются, он удаляет ее, если только ему не встречается ключевое слово
volatile
. Любой вызов функции
asm
может быть перемещен самым непредсказуемым образом. Единственный способ гарантировать конкретный порядок ассемблерных инструкций — включить все нужные инструкции в одну функцию
asm
.

Применение функции

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

9.6. Вопросы сопровождения и переносимости

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

asm
в исходных текстах Linux сгруппировано в файлах
/usr/src/linux/include/asm
и
/usr/src/linux/include/asm-i386
.

Поделиться:
Популярные книги

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»

Фиктивный брак

Завгородняя Анна Александровна
Фантастика:
фэнтези
6.71
рейтинг книги
Фиктивный брак

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Держать удар

Иванов Дмитрий
11. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Держать удар

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Зауряд-врач

Дроздов Анатолий Федорович
1. Зауряд-врач
Фантастика:
альтернативная история
8.64
рейтинг книги
Зауряд-врач

По дороге на Оюту

Лунёва Мария
Фантастика:
космическая фантастика
8.67
рейтинг книги
По дороге на Оюту

Мастер 5

Чащин Валерий
5. Мастер
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Мастер 5

Не лечи мне мозги, МАГ!

Ордина Ирина
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.00
рейтинг книги
Не лечи мне мозги, МАГ!

Измена. Право на семью

Арская Арина
Любовные романы:
современные любовные романы
5.20
рейтинг книги
Измена. Право на семью

Крепость над бездной

Лисина Александра
4. Гибрид
Фантастика:
боевая фантастика
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Крепость над бездной

Неудержимый. Книга XXI

Боярский Андрей
21. Неудержимый
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Неудержимый. Книга XXI