首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按字节填充xmm寄存器

按字节填充xmm寄存器
EN

Stack Overflow用户
提问于 2015-07-21 22:30:27
回答 1查看 527关注 0票数 0

我需要计算存储在一个数组中的32个uint8t值的平均值。出于性能原因,我想更改下面的代码以使用pavgb命令和xmm寄存器。问题是我不能使用movdqu一次复制16个字节,因为我在循环中做了一些计算来得到平均值。下面的代码是我正在使用的实际代码的简化版本。

代码语言:javascript
复制
;
; void average(uint8_t *res, uint8_t *input)
;    rdi = res   | res holds 16 values
;    rsi = input | input holds 32 values
;
segment .text
    global average

average:    
    mov rcx, 0
    xor rax, rax
    xor rbx, rbx
.loop
    mov al, [rsi + rcx]
    cmp al, 16
    jge .endif
    add al, 16

    .endif
    mov bl, [rsi + rcx + 16]
    cmp bl, 16
    jge .endif2
    add bl, 16

    .endif2
    add ax, bl
    shr ax, 1

    mov [rdi], al

    inc rdi
    inc rsi
    inc rcx

    cmp rcx, 16
    jl .loop 

因此,要更改代码以使用xmm寄存器,以便我可以在最后执行类似的操作:

代码语言:javascript
复制
pavgb   xmm0, xmm1
movdqu  [rdi], xmm0

我需要按字节填充xmm0和xmm1寄存器。有没有办法做到这一点呢?

EN

回答 1

Stack Overflow用户

发布于 2015-07-21 22:59:11

使用pavgb指令实际上没有任何意义,因为设置pavgb所需的额外工作远远超过了使用pavgb带来的性能优势。您现有的代码没有问题。

即使使用优化的SSE版本,函数也非常短,因此性能可能会被函数调用开销所淹没。

要获得性能优势,您可能需要使用内部函数,以便编译器能够理解代码,并将其合并到自己的优化中(例如,内联)。

代码语言:javascript
复制
void average(uint8_t *res, uint8_t *input)
{
    auto boundary = __m128i _mm_set1_epi8(0x10);

    // Process the first half
    auto part1 = _mm_loadu_si128((__m128i *)input);
    auto adjust1 = _mm_and_si128(_mm_pcmpgt_epi8(boundary, part1), boundary);
    auto adjusted1 = _mm_add_epi8(part1, adjust1);

   // process the second half
    auto part2 = _mm_loadu_si128((__m128i *)(input + 16);
    auto adjust2 = _mm_and_si128(_mm_pcmpgt_epi8(boundary, part2), boundary);
    auto adjusted2 = _mm_add_epi8(part2, adjust2);

   // average them together
   auto result = _mm_avg_epu8(adjusted1, adjusted2);

   // save the answer
   _mm_storeu_si128((__m128i *)res, result);
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31541961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档