是否存在适用于16位和32位值、类似memset()的高效函数?
针对16/32位值的高效memset替代方案
好问题!确实,memset()靠stosb指令实现了字节级的高速填充,那有没有类似的工具处理16位或32位值呢?咱们来梳理几种靠谱的方案:
1. 手动实现可移植的高效填充函数
标准C库没有专门的16/32位memset,但你可以自己写极简的循环函数,编译器会帮你自动优化成stosw/stosd指令——只要开启了优化(比如-O2及以上)。
比如16位版本:
#include <stdint.h> #include <stddef.h> void memset16(uint16_t *dest, uint16_t value, size_t element_count) { for (size_t i = 0; i < element_count; ++i) { dest[i] = value; } }
32位版本:
void memset32(uint32_t *dest, uint32_t value, size_t element_count) { for (size_t i = 0; i < element_count; ++i) { dest[i] = value; } }
别担心循环效率,主流编译器(GCC、Clang、MSVC)都能识别这种模式,直接把循环替换成rep stosw或rep stosd指令,和memset的底层实现逻辑完全一致,速度一样快。
2. 编译器内置/Intrinsic函数(极致效率)
如果想直接操控底层指令,不依赖编译器优化,很多编译器提供了原生支持的内置函数:
- GCC/Clang:直接用
__builtin_memset16和__builtin_memset32,这些函数是编译器原生实现,会直接生成对应的stos指令,不用自己写循环。 - MSVC:可以用
__stosw和__stosd这些intrinsic函数,用法示例:
这些intrinsic就是直接映射到汇编指令的,完全符合你想要的高效需求。#include <stdint.h> #include <stddef.h> void memset16_msvc(uint16_t *dest, uint16_t value, size_t element_count) { __stosw((unsigned short*)dest, value, element_count); }
3. 为什么不推荐wmemset?
你提到wmemset不可移植且不支持16位,这点完全正确:wmemset是针对宽字符的填充函数,而宽字符的大小在不同平台是不确定的——Windows下是16位,Linux/macOS下是32位。它不是通用的16/32位值填充工具,而且依赖平台的宽字符定义,所以确实不适合用来做跨平台的16位值填充。
总结一下:追求可移植性就用手动循环(编译器会优化);追求极致效率且针对特定编译器,就用内置/intrinsic函数,两者都能高效利用stosw/stosd指令。
内容的提问来源于stack exchange,提问作者CoSoCo
相关产品推荐
相关产品推荐

