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

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

Жанры

Программирование для 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
.

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

Опыты

Монтень Мишель
Научно-образовательная:
философия
7.43
рейтинг книги
Опыты

Добыча. Всемирная история борьбы за нефть, деньги и власть

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

Дважды одаренный. Том VI

Тарс Элиан
6. Дважды одаренный
Фантастика:
аниме
альтернативная история
фэнтези
фантастика: прочее
5.50
рейтинг книги
Дважды одаренный. Том VI

Воины

Хобб Робин
Фантастика:
фэнтези
7.00
рейтинг книги
Воины

Вечера в древности

Мейлер Норман
Проза:
классическая проза
историческая проза
5.00
рейтинг книги
Вечера в древности

Годы странствий

Чулков Георгий Иванович
Документальная литература:
биографии и мемуары
6.25
рейтинг книги
Годы странствий

Цикл романов "Целитель". Компиляция. Книги 1-17

Большаков Валерий Петрович
Целитель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Цикл романов Целитель. Компиляция. Книги 1-17

12

Санивский Сергей Анатолиевич
5.00
рейтинг книги
12

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

Месть Седьмой

Лор Питтакус
5. Наследие Лориена
Фантастика:
фэнтези
9.05
рейтинг книги
Месть Седьмой

Солнечная система (Астрономия и астрофизика)

Сурдин Владимир Георгиевич
Научно-образовательная:
прочая научная литература
астрономия и космос
5.00
рейтинг книги
Солнечная система (Астрономия и астрофизика)

Газлайтер. Том 19

Володин Григорий Григорьевич
19. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
6.25
рейтинг книги
Газлайтер. Том 19

Законы Рода. Том 5

Мельник Андрей
5. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 5

Техники ландшафтной арт-терапии

Копытин Александр Иванович
Научно-образовательная:
психотерапия и консультирование
5.00
рейтинг книги
Техники ландшафтной арт-терапии