linux编程的108种奇淫巧计-11(乱序)

关于下面两段代码的解释:

引自水木Maling:  

"写虽然是16bytes/cycle但那是througput 也就是说我们需要尽可能使每个cycle有一个写操作进入write buffer after allocation stage从而保证 16bytes/cycle. 上面的代码palignr 在前端阻挡(从读取到译码阶段)了写操作尽快的进入decode以及allocatoin stage 所以每个循环会比下面的代码多出 2~3个cycle",该帖子全部内容参见最后的参考阅读。

我将Maling的代码做了一个实现,但由于我试验机不支持SSE3指令,在运行palignr指令会出非法操作,dmesg给出:trap invalid opcode rip:4004cc rsp:7fff74e5b728 error:0,这样的错误,因此改成了三段指令拼的方法。

理解这段代码的功能并不复杂,但为什么快的原因,就是Maling说的那几条,我们可以看出在乱序后性能的提升,这是一个很好的例子,我把它引在了我的系列中,代码和原理来自Maling,我只是包装了下实现,便于大家实际运行,并体验。

 

 

   #include<stdio.h>
   #include<stdlib.h>
   #include <stddef.h>
   #include <stdint.h>
        asm("   .text                        ");
        asm("   .type  shl_7, @function       ");
        asm("shl_7:   push   %rbp                  ");
        asm("   mov    %rsp,%rbp             ");
        asm("loop: sub     $0x80, %rdx        ");
        asm("   movaps  -0x07(%rsi), %xmm1 ");
        asm("   movaps  0x09(%rsi), %xmm2  ");
        asm("   movaps  0x19(%rsi), %xmm3  ");
        asm("   movaps  0x29(%rsi), %xmm4  ");
        asm("   movaps  0x39(%rsi), %xmm5  ");
        asm("   movaps  0x49(%rsi), %xmm6  ");
        asm("   movaps  0x59(%rsi), %xmm7  ");
        asm("   movaps  0x69(%rsi), %xmm8  ");
        asm("   movaps  0x79(%rsi), %xmm9  ");
        asm("   lea     0x80(%rsi), %rsi   ");
        asm("   psrldq  $7, %xmm8          ");
        asm("   pslldq  $9, %xmm9          ");
        asm("   por     %xmm8, %xmm9       ");
        
        asm("   psrldq  $7, %xmm7          ");
        asm("   pslldq  $9, %xmm8          ");
        asm("   por     %xmm7, %xmm8       ");
        
        asm("   psrldq  $7, %xmm6          ");
        asm("   pslldq  $9, %xmm7          ");
        asm("   por     %xmm6, %xmm7       ");

        asm("   psrldq  $7, %xmm5          ");
        asm("   pslldq  $9, %xmm6          ");
        asm("   por     %xmm5, %xmm6       ");

        asm("   psrldq  $7, %xmm4          ");
        asm("   pslldq  $9, %xmm5          ");
        asm("   por     %xmm4, %xmm5       ");

        asm("   psrldq  $7, %xmm3          ");
        asm("   pslldq  $9, %xmm4          ");
        asm("   por     %xmm3, %xmm4       ");

        asm("   psrldq  $7, %xmm2          ");
        asm("   pslldq  $9, %xmm3          ");
        asm("   por     %xmm2, %xmm3       ");


        asm("   psrldq  $7, %xmm1          ");
        asm("   pslldq  $9, %xmm2          ");
        asm("   por     %xmm1, %xmm2       ");

        asm("   movaps  %xmm9, 0x70(%rdi)  ");
        asm("   movaps  %xmm8, 0x60(%rdi)  ");
        asm("   movaps  %xmm7, 0x50(%rdi)  ");
        asm("   movaps  %xmm6, 0x40(%rdi)  ");
        asm("   movaps  %xmm5, 0x30(%rdi)  ");
        asm("   movaps  %xmm4, 0x20(%rdi)  ");
        asm("   movaps  %xmm3, 0x10(%rdi)  ");
        asm("   movaps  %xmm2, 0x0(%rdi)   ");
        asm("   leaveq                          ");
        asm("   retq                            ");

asm("   .text                        ");
        asm("   .type  shl_7_f, @function    ");
        asm("shl_7_f:   push   %rbp          ");
        asm("   mov    %rsp,%rbp             ");
        asm("loop_f: sub     $0x80, %rdx     ");
        asm("   movaps  -0x07(%rsi), %xmm1 ");
        asm("   movaps  0x09(%rsi), %xmm2  ");
        asm("   movaps  0x19(%rsi), %xmm3  ");
        asm("   movaps  0x29(%rsi), %xmm4  ");
        asm("   movaps  0x39(%rsi), %xmm5  ");
        asm("   movaps  0x49(%rsi), %xmm6  ");
        asm("   movaps  0x59(%rsi), %xmm7  ");
        asm("   movaps  0x69(%rsi), %xmm8  ");
        asm("   movaps  0x79(%rsi), %xmm9  ");
        asm("   lea     0x80(%rsi), %rsi   ");
        asm("   psrldq  $7, %xmm8          ");
        asm("   pslldq  $9, %xmm9          ");
        asm("   por     %xmm8, %xmm9       ");
        asm("   movaps  %xmm9, 0x70(%rdi)  ");

        asm("   psrldq  $7, %xmm7          ");
        asm("   pslldq  $9, %xmm8          ");
        asm("   por     %xmm7, %xmm8       ");
        asm("   movaps  %xmm8, 0x60(%rdi)  ");

        asm("   psrldq  $7, %xmm6          ");
        asm("   pslldq  $9, %xmm7          ");
        asm("   por     %xmm6, %xmm7       ");
        asm("   movaps  %xmm7, 0x50(%rdi)  ");


        asm("   psrldq  $7, %xmm5          ");
        asm("   pslldq  $9, %xmm6          ");
        asm("   por     %xmm5, %xmm6       ");
        asm("   movaps  %xmm6, 0x40(%rdi)  ");

        asm("   psrldq  $7, %xmm4          ");
        asm("   pslldq  $9, %xmm5          ");
        asm("   por     %xmm4, %xmm5       ");
        asm("   movaps  %xmm5, 0x30(%rdi)  ");

        asm("   psrldq  $7, %xmm3          ");
        asm("   pslldq  $9, %xmm4          ");
        asm("   por     %xmm3, %xmm4       ");
        asm("   movaps  %xmm4, 0x20(%rdi)  ");

        asm("   psrldq  $7, %xmm2          ");
        asm("   pslldq  $9, %xmm3          ");
        asm("   por     %xmm2, %xmm3       ");
        asm("   movaps  %xmm3, 0x10(%rdi)  ");

        asm("   psrldq  $7, %xmm1          ");
        asm("   pslldq  $9, %xmm2          ");
        asm("   por     %xmm1, %xmm2       ");
        asm("   movaps  %xmm2, 0x0(%rdi)   ");

        asm("   leaveq                          ");
        asm("   retq                            ");

int main(void)
{
        uint8_t * src = (uint8_t*)malloc(sizeof(uint8_t)*(128+7));
        uint8_t * des = (uint8_t*)malloc(sizeof(uint8_t)*128);
        int i = 0;
        for(;i<128;++i)
        {
                src[i] = 0xFF;
        }
        src[0] = 0x0;
        src[1]=0x1;
        src[2]=0x2;
        src[7]=0x7;
        src[8]=0x8;
        src+=7;
        /*shl_7(des,src);
        i = 0;
        for(;i<128;++i)
        {
                printf("%d/n",des[i]);
        }
        i = 0;*/
        for(;i<100000000;++i)
        {

            #ifdef SLOW
                shl_7(des,src);

            #endif

            #ifdef FAST
                shl_7_f(des,src);

            #endif
        }

        return 0;
}

参见:

(1)http://www.newsmth.net/bbscon.php?bid=272&id=47206

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值