• 多媒体指令(内存拷贝加速)


    本来自己写了一个,不过性能竟然和memcpy一样,一点提升都没有,所以有就去网上找了一个性能好的。

    下面的程序是对100MB数据进行内存拷贝.

    我测试了一下。

    直接调用memcpy时间为100ms左右,而asm中的程序能把时间能缩短到80ms左右。

    性能提高的还是很明显的。

    #include <iostream>
    #include <ctime>
    #define  N 100*1024*256
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        float *a;
        float *b;
        a=(float*)malloc(N*sizeof(float));
        b=(float*)malloc(N*sizeof(float));
        for (unsigned long i=0;i<N;++i)
        {
            a[i]=rand();
        }
        unsigned long n=N*sizeof(float);
        void *tbuf;
        tbuf=(void*)malloc(2048);
    
        time_t start,end;
        start=clock();
    
    //    memcpy(b,a,N*sizeof(float));    
        __asm {
                mov esi, [a]
                mov ecx, n
                mov ebx, ecx
                shr ebx, 11 // 2048 bytes at a time
                mov edi, [b]
    
        loop2k: // Copy 2k into temporary buffer
                push edi
                mov edi, tbuf
                mov ecx, 2048
                shr ecx, 6
    
        loopMemToL1:
                prefetchnta 64[esi] // Prefetch next loop, non-temporal
                prefetchnta 96[esi]
    
                movq mm1,  0[esi] // Read in source data
                movq mm2,  8[esi]
                movq mm3, 16[esi]
                movq mm4, 24[esi]
                movq mm5, 32[esi]
                movq mm6, 40[esi]
                movq mm7, 48[esi]
                movq mm0, 56[esi]
    
                movq  0[edi], mm1 // Store into L1
                movq  8[edi], mm2
                movq 16[edi], mm3
                movq 24[edi], mm4
                movq 32[edi], mm5
                movq 40[edi], mm6
                movq 48[edi], mm7
                movq 56[edi], mm0
                add esi, 64
                add edi, 64
                dec ecx
                jnz loopMemToL1
    
                pop edi // Now copy from L1 to system memory
                push esi
                mov esi, tbuf
                mov ecx, 2048
                shr ecx, 6
    
        loopL1ToMem:
                movq mm1, 0[esi] // Read in source data from L1
                movq mm2, 8[esi]
                movq mm3, 16[esi]
                movq mm4, 24[esi]
                movq mm5, 32[esi]
                movq mm6, 40[esi]
                movq mm7, 48[esi]
                movq mm0, 56[esi]
    
                movntq 0[edi], mm1 // Non-temporal stores
                movntq 8[edi], mm2
                movntq 16[edi], mm3
                movntq 24[edi], mm4
                movntq 32[edi], mm5
                movntq 40[edi], mm6
                movntq 48[edi], mm7
                movntq 56[edi], mm0
    
                add esi, 64
                add edi, 64
                dec ecx
                jnz loopL1ToMem
    
                pop esi // Do next 2k block
                dec ebx
                jnz loop2k
                emms;
        }
            
        end=clock();
        cout<<end-start<<endl;
        for (unsigned long i=N-10;i<N;i++)
        {
            cout<<a[i]<<"  "<<b[i]<<endl;
        }
    
        free(a);
        free(b);
        free(tbuf);
        system("pause");
        return 0;
    }

    也可以尝试一下xmm寄存器,一次移动128字节也许性能能提高更多。

  • 相关阅读:
    Executors线程池
    解决HtmlAgilityPack无法获取form标签子节点的问题
    nohup不输出日志信息的方法,及linux重定向学习
    将博客从jekyll迁移到了hexo
    node-webkit中使用sqlite3(MAC平台)
    借助Nodejs在服务端使用jQuery采集17173游戏排行信息
    Shell脚本中的交互式命令处理
    通过桥接虚拟网卡使VMWare和宿主机实现双向通讯
    MySql使用show processlist查看正在执行的Sql语句
    Sql合并两个select查询
  • 原文地址:https://www.cnblogs.com/tiandsp/p/2965015.html
Copyright © 2020-2023  润新知