ассемблерной инструкции 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
.
Глава 10
Безопасность
Одним из основных достоинств Linux является поддержка одновременной работы нескольких пользователей, в том числе по сети. Но у всякой медали есть обратная сторона. В данном случае — это угрозы безопасности, возникающие, когда система подключена к Internet. При благоприятном стечении обстоятельств хакер сможет войти в систему и прочитать, модифицировать или удалить хранящиеся в ней файлы. Кроме того, сами пользователи системы могут получать несанкционированный доступ к чужим файлам.
В ядре Linux есть множество средств, позволяющих предотвратить подобные события. Но защищать следует и обычные приложения. Предположим, к примеру, что разрабатывается бухгалтерская программа. Любой пользователь может зарегистрировать в программе отчет о расходах, но далеко не каждый имеет право утвердить этот отчет. Пользователям разрешается просматривать информацию о своих зарплатах, но, естественно, не о зарплатах своих коллег. Менеджерам может быть разрешено получать данные о зарплатах служащих их отделов, но не служащих других отделов.
Все эти меры предосторожности требуют особого внимания. Очень легко допустить ошибку, из-за которой пользователи смогут делать то, что им не разрешено. Конечно, лучше всего воспользоваться помощью экспертов по системам безопасности. Но базовыми знаниями должен владеть любой разработчик программного обеспечения.
10.1. Пользователи и группы
В Linux каждому пользователю назначается уникальный номер, называемый его
С одним идентификатором может быть связано несколько пользовательских имен. С точки зрения системы это не имеет никакого значения и не представляет для нее проблемы: она учитывает только идентификатор. Пользовательские имена совершенно равноправны, если им соответствует одинаковый идентификатор.