快速内存拷贝

C语言自带memcpy已优化的很好了,通过拷贝一幅图像,测得耗时为1.8ms,经过很多其他方法代换,都无法达到如此速度,为了提速,经过摸索,终于找到更快一点的方法。经测得耗时为1.35ms。

内存拷贝程序

void MemCopy(void *pDst, void *pSrc, DWORD dwSize)//顺序拷贝
{
	_asm
	{
		    mov esi, pSrc;  //传递源指针
		    mov edi, pDst;  //传递目标指针
		    mov ebx, dwSize;//ebx 字节计数
		    shr ebx, 7;     //除 128 (8 * 128bit registers)
	  L1:
		    movdqu xmm0, 0[ESI]; //从内存移动数据到寄存器
		    movdqu xmm1, 16[ESI];
		    movdqu xmm2, 32[ESI];
		    movdqu xmm3, 48[ESI];
		    movdqu xmm4, 64[ESI];
		    movdqu xmm5, 80[ESI];
		    movdqu xmm6, 96[ESI];
		    movdqu xmm7, 112[ESI];

		    movntdq 0[EDI], xmm0; //从寄存器移动数据到内存
		    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; //减1
		    jnz L1;  //不为0循环

	  	    mov ecx, dwSize;
		    and ecx, 127;
		    rep movsb; //余数循环
	}
}

用完了8个多媒体寄存器,每个寄存器每次传输16个字节,用到了内存拷贝极限。

在vs2017的C++调试通过。

原文地址:https://www.cnblogs.com/hbg200/p/9563283.html

时间: 2024-10-25 21:57:36

快速内存拷贝的相关文章

好记性不如烂笔头5-JAVA快速文件拷贝

如果使用luncene或者hadoop等文件系统的话,有大量的索引文件需要分发,可以利用现成的分发工具,也可以自己写程序进行快速的文件拷贝: 使用NIO进行快速的文件拷贝 package com.daily; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileCh

CUDA内存拷贝

原文链接1.cudaMemcpy()<--> cudaMalloc()  //线性内存拷贝 1 //线性内存拷贝 2 cudaMalloc((void**)&dev_A, data_size); 3 cudaMemcpy(dev_A, host_A, data_size, cudaMemcpyHostToDevice); 2.cudaMemcpy2D()<-->cudaMallocPitch() //线性内存拷贝 cudaError_t cudaMemcpy2D( void

【内存类操作】浅谈内存拷贝异常

结合本人在实际项目中所积累的经验,以及曾经犯过的错误,堆内存操作类函数做一个简单的剖析,抛砖引玉,欢迎大家吐槽. 首先,讲一下内存使用异常发生的几种场景. 1.野指针的使用,使用已经释放的指针,如果向野指针中写内容,就极有可能导致设备重启或任务挂死.因为,正在运行的任务的地址被意外的改写. [避免策略]函数入参要判空,指针使用(包括释放)之前一定要释放. 2.内存函数的错误使用: void *memset(void *s, int ch, size_t n); c语言中在<memory.h>或

memcpy内存拷贝及优化策略图解

一般内存拷贝与优化 代码实现 #include<iostream> usingnamespace std; //不安全的内存拷贝(当源内存地址与目标内存地址重叠时会产生错误) void h_memcpy(void*src,void *dst,intsize){ if (src == NULL|| dst == NULL) { return; } const char *s =(char *)src; char *d = (char*)dst; while (size--) { *d++ = *

CUDA零内存拷贝 疑问考证

今天思考了一下CUDA零内存拷贝的问题,感觉在即将设计的程序中会派上用场,于是就查了一下相关信息. 以下是一些有帮助的链接: cuda中的零拷贝用法--针对二维指针 cuda中的零拷贝用法--针对一维指针 cuda零拷贝用法-二维结构体指针 浅谈CUDA零拷贝内存 经过调查发现,零拷贝技术适用于集中计算.较少内存拷贝次数的问题.比如向量点积.求和运算等问题. 既然零拷贝技术是在CPU上开辟内存空间,GPU可以直接访问该空间,那么我就产生了一个疑问:"如果CPU上开辟的空间大于GPU的可用空间的时

【C语言】 字符串操作函数及内存拷贝函数归总

今天在这里把零散的一些常用的字符串操作函数和内存拷贝函数进行一下归总实现. 一 . 字符串操作函数 字符串操作函数有很多,这里我列举一些常用的函数,以及自实现的代码: 字符串拷贝函数: 函数原型: char* my_strcpy(char* dst,const char* src) strcpy(): char* my_strcpy(char* dst,const char* src) {     assert(dst);     assert(src);     char *ret = dst

转载:内存拷贝MEMCPY()与VMSPLICE()性能对比

内存拷贝MEMCPY()与VMSPLICE()性能对比 综述 在上一篇文章<进程间大数据拷贝方法调研>中介绍和对比了三种A进程读取文件然后拷贝给B进程的方法,测试结果显示在涉及到内存与磁盘间的数据传输时,splice方法由于避免了内核缓冲区与用户缓冲区之间的多次数据拷贝,表现最好.但是由于这种对比限定在包含I/O读写,且进程不能对数据进行修改的特殊情景中,毕竟在实际情况下不太常见,理论意义大于实际意义. 那本文要探讨的情景,在实际编程过程中就十分常见了: A进程的内存中有一大块数据,要传递给B

c++中内存拷贝函数(C++ memcpy)详解

原型:void*memcpy(void*dest, const void*src,unsigned int count); 功能:由src所指内存区域复制count个字节到dest所指内存区域. 说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针. 举例: // memcpy.c #include <stdlib.h> #include <string.h> main() { char *s= "Golden Global View "; c

C++ 内存拷贝函数 memcpy

在C/C++中经常会遇到对一段固定的连续内存进行拷贝操作,   这时候我们就需要用到   <cstring>  头文件  中的  memcpy  函数. 具体使用如下: 其中   ,   y 为 拷贝到的内存段 开始地址,     x   为   从拷贝一方的  内存段  开始地址. 第三个参数为拷贝的内存字节数,这里采用  sizeof  对类型的字节数进行判断.