Сводная характеристика качества оптимизации штатных Си функций и функций ОС для работы с памятью
Качество оптимизации штатных функций, поставляемых вместе с компилятором, – весьма актуальный вопрос, поскольку от этого напрямую зависит производительность откомпилированной программы.
Вообще же, отношения к штатным функциям у программистов самые разнообразные: от полного нежелания использовать что-либо стандартное (стандартные вещи редко бывают хорошими), до безоговорочного их обожания (не надо думать, что разработчики компилятора глупее нас с вами).
Как же действительно обстоят дела на практике? Об этом можно узнать из таблицы ???3, приведенной ниже и описывающие ключевые особенности оптимизации базовых memory-функций популярных компиляторов и операционной системы Windows 2000. (Операционная система приведена лишь в качестве примера, т.к. использование функций семейства RtlxxxMemory, как было показано выше нецелесообразно – см. "Особое замечание по функциями Win32 API"):
memcpy/CopyMemory
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
копирование
DWORD
DWORD
DWORD
DWORD
––
выравнивание адресов источника и/или приемника
выравнивает адрес приемника по границе 4 байт
не выравнивает
не выравнивает
не выравнивает
––
memmove/MoveMemory
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
копирование не перекрывающихся блоков памяти
DWORD, в прямом направлении
–
DWORD, в прямом направлении
DWORD, в прямом направлении
DWORD, в прямом направлении
копирование перекрывающихся блоков памяти пр
src < dst
DWORD, в обратном направлении
–
DWORD, в обратном направлении
BYTE?, в обратном направлении
DWORD, в обратном направлении
src > dst
DWORD, в прямом направлении
–
DWORD, в прямом направлении
DWORD, в прямом направлении
DWORD, в прямом направлении
выравнивание адресов источника и/или приемника
выравнивает адрес приемника по границе 4 байт
–
не выравнивает
не выравнивает
не выравнивает
<
В таблицах, приведенных ниже, содержится краткая характеристика качества оптимизации штатных Си-функций и функций операционной системы для работы со строками. Обратите внимание: ни операционная система, ни библиотеки распространенных компиляторов не являются полностью оптимальными и резерв для повышения быстродействия еще есть!
Поэтому, целесообразнее пользоваться вашими собственными реализациями строковых функций, вылизанных "по самые помидоры". Если этого не сделаете вы, никто не оптимизирует вашу программу за вас!
strlen/lstrlenA
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
определение длины
align
unalign
BYTE, в прямом направлении
DWORD, в прямом направлении
BYTE, в прямом направлении
BYTE, в прямом направлении
dword
byte
выравнивание адресов источника и/или приемника
не выравнивает
не выравнивает
выравнивает по границе 4 байт
не выравнивает
не выравнивает
степень разворота цикла (итераций)
1
1
1
1
1
strcpy/lstrcpyA
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
копирование
определение длины источника
не определяет
BYTE
BYTE
BYTE
BYTE
перенос строки
align
unalign
DWORD
DWORD
DWORD
dword
byte
выравнивание адресов источника и/или приемника
не выравнивает
не выравнивает
не выравнивает
не выравнивает
не выравнивает
степень разворота цикла (итераций)
1
1
1
2
1
strcat/lstrcatA
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
копирование
определение длины источника
не определяет
BYTE
BYTE
BYTE
BYTE
определение длины приемника
align
unalign
BYTE
BYTE
не определяет
BYTE
dword
byte
перенос строки
align
unalign
DWORD
DWORD
BYTE
DWORD, в прямом направлении
dword
byte
выравнивание адресов источника и/или приемника
не выравнивает
не выравнивает
не выравнивает
не выравнивает
не выравнивает
степень разворота цикла (итераций)
1
1
1
2
1
<
memset/FillMemory/ZeroMemory
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
заполнение памяти
DWORD, в прямом направлении
DWORD, в прямом направлении
DWORD, в прямом направлении
DWORD, в прямом направлении
DWORD, в прямом направлении
выравнивание адреса приемника
выравнивает адрес приемника по границе 4 байт
не выравнивает
не выравнивает
не выравнивает
не выравнивает
memcmp/CompareMemory
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
сравнение памяти
BYTE, в прямом направлении
BYTE, в прямом направлении
BYTE, в прямом направлении
BYTE, в прямом направлении
DWORD, в прямом направлении
выравнивание адресов источника и/или приемника
не выравнивает
не выравнивает
не выравнивает
не выравнивает
не выравнивает
Таблица 3 Сводная характеристика качества оптимизации штатных Си функций и функций ОС для работы с памятью
Что полезного можно почерпнуть из этой таблицы? Первое, что сразу бросается в глаза: крайне небрежная оптимизация штатных функций в компиляторах от Borland и WATCOM. Создается впечатление, что их разработчики вообще не ставили перед собой задачу достичь если не максимальной, то хотя бы приемлемой производительности.
Гораздо качественнее оптимизированы memory-функции штатной библиотеки компилятора Microsoft Visual C++, которые выгодно отличаются тем, что выравнивают адрес приемника на границу 4 байт, что в ряде случаев значительно увеличивает производительность (правда, как было показано в главе "Выравнивание данных" гораздо предпочтительнее выравнивать адрес источника, а не приемника). Тем не менее Microsoft Visual C++ не использует никаких прогрессивных алгоритмов оптимизации, описанных в главе "Оптимизация штатных Си-функций для работы с памятью", а функции memcmp он не оптимизирует вообще!
Словом, если вам нужна скорость – используйте собственные реализации функций для работы с памятью!
strcmp/lstrcmpA
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
проверка
BYTE, в прямом направлении
BYTE
BYTE
DWORD, в прямом направлении
BYTE, в прямом направлении
выравнивание адресов источника и/или приемника
не выравнивает
не выравнивает
не выравнивает
не выравнивает
не выравнивает
степень разворота цикла (итераций)
2
2
2
8 (!)
1
strstr/---
Microsoft Visual C++ 6.0
Borland C++ 5.5
WATCOM C++ 10
Windows 2000
LIB
intrinsic
сравнение
BYTE, в прямом направлении
–
DWORD, в прямом направлении
BYTE, в прямом направлении
–
выравнивание адресов источника и/или приемника
не выравнивает
–
не выравнивает
не выравнивает
–
степень разворота цикла (итераций)
1
–
1
1
–
Таблица 4 Сводная таблица качества оптимизации штатных Си функций и функций ОС для работы со строками