Есть ли функция memset () для 16- и / или 32-битных значений? - PullRequest
1 голос
/ 19 апреля 2019

memset() очень быстрый, поскольку он извлекает выгоду из stosb кода операции внутри.Существует ли функция для 16 и 32-битных значений, которая аналогично эффективно выигрывает от stosb, stosw и / или stosd?

wmemset() не является переносимой и не помогает для 16-битных значений.

Ответы [ 2 ]

3 голосов
/ 19 апреля 2019

В стандартном C такой функции нет, но в зависимости от того, что вы пытаетесь сделать, могут существовать «встроенные функции» SIMD для конкретного процессора, которые вы можете использовать для их создания. Ваше упоминание stosb заставляет меня думать, что вы используете x86, поэтому просмотрите документацию по различным *mmintrin.h заголовкам и функциям, которые они предоставляют.

0 голосов
/ 19 апреля 2019

Да, это во многих вариантах.

например

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;
}
...