是否有用于16位和/或32位值的memset()函数?

时间:2019-04-19 14:05:07

标签: c memset

memset()非常快,因为它在内部受益于stosb操作码。 是否有16位和32位值的函数可以从stosbstosw和/或stosd中类似地有效地受益?

wmemset()不可移植,对16位值无济于事。

2 个答案:

答案 0 :(得分:3)

标准C中没有这样的功能,但是根据您要尝试执行的操作,可能会使用特定于CPU的SIMD“内部功能”来构建一个。您对stosb的提及使我认为您使用的是x86,因此请查看文档中有关各种*mmintrin.h标头及其提供的功能的信息。

答案 1 :(得分:0)

是的,它有很多变体。

例如

void *memset16(void *m, uint16_t val, size_t count)
{
    uint16_t *buf = m;

    while(count--) *buf++ = val;
    return m;
}

void *memset32(void *m, uint32_t val, size_t count)
{
    uint32_t *buf = m;

    while(count--) *buf++ = val;
    return m;
}

void *memsetXX(void *m, void *val, size_t size, size_t count)
{
    char *buf = m;

    while(count--)
    {
        memcpy(buf, val, size);
        buf += size;
    }
    return m;
}

安全版本:

void *memset16safe(void *m, uint16_t val, size_t count)
{
    char *buf = m;
    union 
    {
        uint8_t d8[2];
        uint16_t d16;
    }u16 = {.d16 = val};

    while(count--) 
    {
        *buf++ = u16.d8[0];
        *buf++ = u16.d8[1];
    }
    return m;
}

void *memset32(void *m, uint32_t val, size_t count)
{
    char *buf = m;
    union 
    {
        uint8_t d8[4];
        uint32_t d32;
    }u32 = {.d32 = val};

    while(count--) 
    {
        *buf++ = u32.d8[0];
        *buf++ = u32.d8[1];
        *buf++ = u32.d8[2];
        *buf++ = u32.d8[3];
    }
    return m;
}