Инженер из Intel, Ноах Голдштейн, оптимизировал функцию memset()
в библиотеке glibc. Данная оптимизация даёт прирост в производительности порядка 7.5% на десктопных версиях процессоров архитектур Skylake-X и Ice Lake. У серверных версий прирост в производительности немного ниже, прежде всего из-за более низкой общей производительности одиночного ядра.
В прежней реализации функции memset()
использовалась ассемблерная инструкция rep stosb
. До недавнего времени эта инструкция работала достаточно быстро, за счёт внутрипроцессорной оптимизации zero-over-zero writeback. Однако в этой оптимизации была найдена потенциальная уязвимость, которая может привести к атаке по побочному каналу. В результате оптимизация zero-over-zero writeback была отменена, что и привело к ухудшению производительности rep stosb
. В новой версии memset()
инструкция rep stosb
всё ещё используется, но при выполнении более строгих условий.
Что именно изменилось, можно понять по изменению следующего комментария в коде, который описывает подробности реализации memset()
Прежняя версия описания:
/* memset is implemented as:
1. Use overlapping store to avoid branch.
2. If size is less than VEC, use integer register stores.
3. If size is from VEC_SIZE to 2 * VEC_SIZE, use 2 VEC stores.
4. If size is from 2 * VEC_SIZE to 4 * VEC_SIZE, use 4 VEC stores.
5. On machines ERMS feature, if size is greater or equal than
__x86_rep_stosb_threshold then REP STOSB will be used.
6. If size is more to 4 * VEC_SIZE, align to 4 * VEC_SIZE with
4 VEC stores and store 4 * VEC at a time until done. */
Новая версия описания:
/* memset is implemented as:
1. Use overlapping store to avoid branch.
2. If size is less than VEC, use integer register stores.
3. If size is from VEC_SIZE to 2 * VEC_SIZE, use 2 VEC stores.
4. If size is from 2 * VEC_SIZE to 4 * VEC_SIZE, use 4 VEC stores.
5. If size is more to 4 * VEC_SIZE, align to 1 * VEC_SIZE with
4 VEC stores and store 4 * VEC at a time until done.
6. On machines ERMS feature, if size is range
[__x86_rep_stosb_threshold, __x86_memset_non_temporal_threshold)
then REP STOSB will be used.
7. If size >= __x86_memset_non_temporal_threshold, use a
non-temporal stores. */
>>> Подробности