精确拷贝到字节,三种拷贝方式:1. movsd 2.SSE 系列 + 软预取 3.SSE系列+硬预取方式,要注意的是,不是所有的拷贝SSE都更优,正如为了行进100米,是开飞机还是步行咧?嘿嘿。所以,对于小字节量拷贝用movsd、 movsb过渡。

测试平台(CPU-Z):

Intel(R) Celeron(R) CPU 2.66GHz

支持的指令集:MMX,SSE(1,2,3) ,EM64T

一级数据缓存:16KB

二级数据缓存:256KB

测试32.1 MB文件存拷贝:

_fast_memcpy1 (movsd) 33 ms

_fast_memcpy9 (SSE 系列+软预取) 23 ms

_block_prefetch (硬预取 block_size 8KB) 22 ms

代码: ;************************************************************ ;-==-: fast_memcpyTest By G-Spider @2010 ;-==-: ml /c /coff memcpyTest.asm 注意,请用6.15以上的版本 ;-==-: link /subsystem:console memcpyTest.obj ;************************************************************ .686p .XMM .model flat,stdcall option casemap:none include windows.inc include user32.inc include kernel32.inc include msvcrt.inc includelib user32.lib includelib kernel32.lib includelib msvcrt.lib BLOCK_SIZE equ 8192 .data dwlm dd 1000 ;1000是毫秒为单位,1000000则是微秒为单位 fmt db '计算用时:',0dh,0ah,0 fmt1 db '%6lld ms',0dh,0ah,0 szFileName db 'xinyu.avi',0 ;32,954KB 原文件 szOutName db 'output.avi',0 ;输出文件; ;szFileName db 'test.png',0 ;63KB 请以微秒为单位 原文件 ;szOutName db 'output.png',0 ;输出文件 szPause db 'Pause',0 .data? hHandle dd ? hHandle1 dd ? lpInputBuf dd ? lpOutputBuf dd ? dwStrlen dd ? lpNumberOfBytes dd ? dwOldProcessP dd ? dwOldThreadP dd ? ;------------------------------------- dqTickCounter1 dq ? dqTickCounter2 dq ? dqFreq dq ? dqTime dq ? .code ;************************************* _fast_memcpy1 proc lpdst,lpsrc,dwlen ;%define param esp+8+4 ;%define src param+0 ;%define dst param+4 ;%define len param+8 mov esi, lpsrc ; source array mov edi, lpdst ; destination array mov ecx, dwlen mov eax,ecx and eax,3 shr ecx, 2 ; convert to DWORD count test ecx,ecx jz A000 rep movsd A000: test eax,eax jz A001 mov ecx,eax rep movsb A001: xor eax,eax ret _fast_memcpy1 endp ;*************************************** _fast_memcpy9 proc lpdst,lpsrc,dwlen mov esi, lpsrc ;src pointer mov edi, lpdst ;dest pointer mov ebx, dwlen ;ebx is our counter mov ecx, ebx and ecx, 07fh ;剩余的<128字节 shr ebx, 7 ;divide by 128 (8 * 128bit registers) test ebx,ebx jz A000 ALIGN 16 loop_copy: prefetchnta 128[ESI]; SSE2 prefetch prefetchnta 160[ESI]; prefetchnta 192[ESI]; prefetchnta 224[ESI]; movdqa xmm0, 0[ESI] ; move data from src to registers movdqa xmm1, 16[ESI]; movdqa xmm2, 32[ESI]; movdqa xmm3, 48[ESI]; movdqa xmm4, 64[ESI]; movdqa xmm5, 80[ESI]; movdqa xmm6, 96[ESI]; movdqa xmm7, 112[ESI]; movntdq 0[EDI], xmm0 ; move data from registers to dest movntdq 16[EDI], xmm1; movntdq 32[EDI], xmm2; movntdq 48[EDI], xmm3; movntdq 64[EDI], xmm4; movntdq 80[EDI], xmm5; movntdq 96[EDI], xmm6; movntdq 112[EDI], xmm7; add esi, 128; add edi, 128; dec ebx; jnz loop_copy; //loop please sfence align 16 A000: mov eax, ecx and eax, 3 shr ecx, 2 ; convert to DWORD count test ecx,ecx jz short A001 rep movsd A001: test eax,eax jz A002 mov ecx,eax rep movsb A002: xor eax,eax ret _fast_memcpy9 endp ;***************************************************** _block_prefetch proc lpdst,lpsrc,dwlen mov edi, lpdst mov esi, lpsrc mov eax, dwlen mov edx, eax and eax, (BLOCK_SIZE-1) ;4096-1=0fffh ;8192-1=1fffh;16*1024-1=3fffh and edx, 0ffffe000h ;与 BLOCK_SIZE有关 test edx,edx jz A000 align 16 main_loop: xor ecx,ecx align 16 prefetch_loop: movaps xmm0, [esi+ecx] movaps xmm0, [esi+ecx+64] add ecx,128 cmp ecx,BLOCK_SIZE jne prefetch_loop xor ecx,ecx align 16 cpy_loop: movdqa xmm0,[esi+ecx] movdqa xmm1,[esi+ecx+16] movdqa xmm2,[esi+ecx+32] movdqa xmm3,[esi+ecx+48] movdqa xmm4,[esi+ecx+64] movdqa xmm5,[esi+ecx+16+64] movdqa xmm6,[esi+ecx+32+64] movdqa xmm7,[esi+ecx+48+64] movntdq [edi+ecx],xmm0 movntdq [edi+ecx+16],xmm1 movntdq [edi+ecx+32],xmm2 movntdq [edi+ecx+48],xmm3 movntdq [edi+ecx+64],xmm4 movntdq [edi+ecx+80],xmm5 movntdq [edi+ecx+96],xmm6 movntdq [edi+ecx+112],xmm7 add ecx,128 cmp ecx,BLOCK_SIZE jne cpy_loop add esi,ecx add edi,ecx sub edx,ecx jnz main_loop sfence align 16 A000: mov ecx, eax and eax, 3 shr ecx, 2 ; convert to DWORD count test ecx,ecx jz short A001 rep movsd A001: test eax,eax jz A002 mov ecx,eax rep movsb A002: xor eax,eax ret _block_prefetch endp ;***************************************************** start: invoke CreateFile,offset szFileName,GENERIC_READ,FILE_SHARE_READ,/ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL .if eax == INVALID_HANDLE_VALUE invoke MessageBox,NULL,0,0,0 .endif mov hHandle,eax invoke GetFileSize,eax,NULL mov dwStrlen,eax add eax,16 invoke crt_malloc,eax mov lpInputBuf,eax mov edx,lpInputBuf and eax,0fh jz Good1 xor eax,edx add eax,10h mov lpInputBuf,eax Good1: invoke RtlZeroMemory,lpInputBuf,dwStrlen invoke ReadFile,hHandle,lpInputBuf,dwStrlen,offset lpNumberOfBytes,NULL mov eax,dwStrlen add eax,16 invoke crt_malloc,eax mov lpOutputBuf,eax mov edx,lpOutputBuf and eax,0fh jz Good2 xor eax,edx add eax,10h mov lpOutputBuf,eax Good2: invoke RtlZeroMemory,lpOutputBuf,dwStrlen ;---------------------------------------------------- invoke crt_printf,offset fmt mov ecx,5 ;测试5次 .while ecx!=0 push ecx invoke GetCurrentProcess invoke GetPriorityClass,eax mov dwOldProcessP,eax invoke GetCurrentThread invoke GetThreadPriority,eax mov dwOldThreadP,eax invoke GetCurrentProcess invoke SetPriorityClass,eax,REALTIME_PRIORITY_CLASS invoke GetCurrentThread invoke SetThreadPriority,eax,THREAD_PRIORITY_TIME_CRITICAL ;-------------------------------------------------- invoke QueryPerformanceCounter,addr dqTickCounter1 ;时间测试 ;invoke _fast_memcpy1,lpOutputBuf,lpInputBuf,dwStrlen ;invoke _fast_memcpy9,lpOutputBuf,lpInputBuf,dwStrlen invoke _block_prefetch,lpOutputBuf,lpInputBuf,dwStrlen ;测试结束 invoke QueryPerformanceCounter,addr dqTickCounter2 invoke QueryPerformanceFrequency,addr dqFreq mov eax,dword ptr dqTickCounter1 mov edx,dword ptr dqTickCounter1[4] sub dword ptr dqTickCounter2,eax sub dword ptr dqTickCounter2[4],edx ;---------------------------------------------------- ;优先级还原 invoke GetCurrentThread invoke SetThreadPriority,eax,dwOldThreadP invoke GetCurrentProcess invoke SetPriorityClass,eax, dwOldProcessP finit fild dqFreq fild dqTickCounter2 fimul dwlm fdivr fistp dqTime ;dqTime中的64位值就是时间间隔(以微秒为单位) ;--------------------------------------------------- invoke crt_printf,offset fmt1,dqTime pop ecx dec ecx .endw ;输出copy文件 invoke CreateFile,offset szOutName,GENERIC_WRITE,FILE_SHARE_READ,/ NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL .if eax == INVALID_HANDLE_VALUE invoke MessageBox,NULL,0,0,0 .endif mov hHandle1,eax invoke WriteFile,eax,lpOutputBuf,dwStrlen,offset lpNumberOfBytes,NULL invoke CloseHandle,hHandle invoke CloseHandle,hHandle1 invoke crt_system,offset szPause invoke ExitProcess,0 end start

快速存拷贝 fast_memcpy相关推荐

  1. 结构体内存拷贝的两种方法

    结构体内存拷贝的两种方法 前言 内容 总结 前言 最近看一些代码,发现内存拷贝的两种方式,下面我就来介绍一下两种方式. 内容 首先定义一个结构体processorHead.h: #pragma pac ...

  2. java拷贝压缩文件_Android java, 快速文件拷贝,文件压缩,获得系统时间 | 学步园...

    1. 最快速度的文件拷贝,管道对管道. /** * Create report file. * @param srcFile * @param dstFile */ private void Crea ...

  3. 两台电脑间大量数据拷贝的快捷方法

    可能大家会遇到需要将一台电脑里的数据拷贝到另外一台电脑,最常用的方法是用u盘或移动硬盘等存储设备来拷贝,这样速度慢,而且可能拷贝多次才能将数据拷贝完.现提供一种方法,就是通过windows 的文件共享 ...

  4. 模型训练太慢?显存不够?这个方法让你的GPU联手CPU

    随着深度学习模型复杂度和数据集规模的增大,计算效率成为了不可忽视的问题.GPU凭借强大的并行计算能力,成为深度学习加速的标配.然而,由于服务器的显存非常有限,随着训练样本越来越大,显存连一个样本都容不 ...

  5. 【GPU结构与CUDA系列4】GPU存储资源:寄存器,本地内存,共享内存,缓存,显存等存储器细节

    0 软件抽象和硬件结构对应关系的例子 把GPU跟一个学校对应起来,学校里有教学楼.操场.食堂,还有老师和学生们:很快有领导(CPU)来检查卫生(需要执行的任务Host程序),因此这个学校的学生们要完成 ...

  6. Windows xcopy 增量拷贝(增量复制)方法

    xcopy S D /e /d 实现快速增量拷贝 学linux发现Windows也支持增量拷贝,非常实用的小方法 /e 表示复制目录和子目录,包括空的 /d:月-日-年 表示复制在指定日期及其后发生更 ...

  7. eclipse你的主机中的软件中止了一个已建立的连接。_如何备份/恢复一个基于Windows系统的操作面板?...

    说明: 对于基于 Windows 系统面板有两种组态备份的选项,而不必获得 ProTool 或 WinCC flexible 的原程序: A. 使用 ProSave 备份/恢复 B. 使用存储卡备份/ ...

  8. MT7621_移植篇(3) uboot编译+配置项分析

    U-Boot("通用引导加载程序",通常简称为U-Boot)是一种开源的主引导加载程序,用于嵌入式设备中打包引导设备操作系统内核的指令.它可用于多种计算机架构,包括68k.ARM. ...

  9. Java面试题大全(Android版)

    疯狂Java面试题大全(Android版) Java核心技术部分 Java核心技术部分的面试题,可能覆盖Java基本语法.面向对象(包括类定义.方法.构造器.递归.继承.抽象类.接口.枚举以及fina ...

最新文章

  1. list index out of range怎么解决_“卿卿我我”和“如胶似漆”英语怎么说?
  2. 使用Linq判断DataTable数据是否重复
  3. [SCOI2014]方伯伯的OJ
  4. 带宽测量:带宽测量工具下载
  5. Buck-Boost变换
  6. C#Linq的10个练习
  7. linux期末考试试题4,Linux试题4
  8. java wait api_java API 文档
  9. 曼哈顿交易 - 题解
  10. jQuery学习整理 (3) 使用jQuery操作元素的属性与样式
  11. SGX中的X特性、SGX获取元数据
  12. Lucene的各中文分词比较
  13. splunk篇5-导出csv文件中文乱码
  14. 为什么计算机日期最早1970,计算机时间基准——1970.1.1
  15. vue/cli删除预设记录
  16. 字节跳动2021批笔试题解
  17. Django视图学习——处理Http404异常
  18. JNA的正确打开方式
  19. 实战录 | 基于openflow协议的抓包分析
  20. 图片加水印怎么弄?小白都会的加水印方法

热门文章

  1. 2019阿里校招测评题,光明小学完全图最短路径问题
  2. import open3d:GLIBC_2.18 not found
  3. 不装了,我摊牌了,我来拿勋章的
  4. 高效多用的群集之LVS负载均衡群集(NAT模式)
  5. 读书笔记【顾行发,航天光学遥感器辐射定标原理与方法】
  6. js循环方法之 for forEach each map
  7. 吃鸡游戏(18.11.24)
  8. 用 Python 和 EV 剪辑短视频
  9. May Cordova anonymously report usage statistics to improve the tool over time?
  10. 计算机行显示性能调整,Win7系统优化小技巧调整效率