memcpy/memmove?快速乘?
memcpy?memmove?
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int n=;
int a[n+],b[n+],c[n+],d[n+],e[n+],f[n+];
int main()
{
int i;
srand();
for(i=;i<=n;i++) a[i]=rand();
clock_t st1=clock();
memcpy(b+,a+,sizeof(int)*n);
clock_t ed1=clock();
clock_t st2=clock();
memmove(c+,a+,sizeof(int)*n);
clock_t ed2=clock();
clock_t st3=clock();
for(i=;i<=n;i++) d[i]=a[i];
clock_t ed3=clock();
clock_t st4=clock();
for(i=;i<=n-;i+=)
{
e[i]=a[i];
e[i+]=a[i+];
e[i+]=a[i+];
e[i+]=a[i+];
}
(i<=n)&&(e[i]=a[i]);
(i+<=n)&&(e[i+]=a[i+]);
(i+<=n)&&(e[i+]=a[i+]);
clock_t ed4=clock();
clock_t st5=clock();
for(i=;i<=n-;i+=)
{
f[i]=a[i];
f[i+]=a[i+];
f[i+]=a[i+];
f[i+]=a[i+];
f[i+]=a[i+];
f[i+]=a[i+];
f[i+]=a[i+];
f[i+]=a[i+];
}
(i<=n)&&(f[i]=a[i]);
(i+<=n)&&(f[i+]=a[i+]);
(i+<=n)&&(f[i+]=a[i+]);
(i+<=n)&&(f[i+]=a[i+]);
(i+<=n)&&(f[i+]=a[i+]);
(i+<=n)&&(f[i+]=a[i+]);
(i+<=n)&&(f[i+]=a[i+]);
clock_t ed5=clock();
cout<<"time1:"<<ed1-st1<<' '<<memcmp(a+,b+,sizeof(int)*n)<<'\n';
cout<<"time2:"<<ed2-st2<<' '<<memcmp(a+,c+,sizeof(int)*n)<<'\n';
cout<<"time3:"<<ed3-st3<<' '<<memcmp(a+,d+,sizeof(int)*n)<<'\n';
cout<<"time4:"<<ed4-st4<<' '<<memcmp(a+,e+,sizeof(int)*n)<<'\n';
cout<<"time5:"<<ed5-st5<<' '<<memcmp(a+,f+,sizeof(int)*n)<<'\n';
return ;
}
不开优化:
time1:139254 0
time2:198093 0
time3:601853 0
time4:588247 0
time5:598584 0
O2:
time1:138256 0
time2:139235 0
time3:426570 0
time4:322532 0
time5:301933 0
Ofast:
time1:137893 0
time2:140585 0
time3:422154 0
time4:309306 0
time5:298620 0
很显然在大数据(n=50000000)下memcpy最快
另外,在小数据(比如n=26)下,测试得到明显直接赋值(time3)最快
在较小数据(比如n=1000)下,测试得到memmove最快?
快速乘
测试对比程序:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll rd()
{
return rand()|(ll(rand())<<);
}
ll md;
ll mul1(ll x,ll y)
{
x%=md;y%=md;
ll t=x*y-ll((long double)x/md*y+0.5)*md;
return t<?t+md:t;
}
ll mul2(ll x,ll y)
{
x%=md;y%=md;
ll t=x*y-ll((long double)x*y/md+0.5)*md;
return t<?t+md:t;
}
ll mul3(ll x,ll y)
{
x%=md;y%=md;
ll t=x*y-ll((long double)x/md*y+1e-)*md;
return t<?t+md:t;
}
ll mul0(ll x,ll y)
{
return __int128(x)*y%md;
}
ll a,b;
int main()
{
int T=;
srand();
while()
{
T++;
ll a=rd(),b=rd();
md=rd();//%ll(1e18);
//cout<<a<<' '<<b<<' '<<md<<'\n';
ll t1=mul1(a,b),t2=mul0(a,b);//可将mul1改为mul2/mul3
//cout<<t1<<' '<<t2<<'\n';
if(t1!=t2)
{
printf("%d\n",T);
puts("test");
int t;cin>>t;
}
//int t;cin>>t;
}
return ;
}
经过一些测试,可以发现,mul3效果最差(在模数>=1e17时,100000组以内就拍出锅);应该是1e-8不够
mul2效果没有mul1好(模数不设额外上限时,100000组以内出锅;上限1e18时,20秒不出锅)
mul1效果最好(模数不设额外上限时,20秒不出锅)
原因就不知道了。。。
memcpy/memmove?快速乘?的更多相关文章
- 自己实现的库函数2(memset,memcmp,memcpy,memmove)
		memset,memcmp,memcpy,memmove是对内存进行管理的库函数,为了更好的理解和使用这几个函数,自己用C语言实现一下~ //内存设置函数void* my_memset(void* d ... 
- memset memcmp memcpy memmove 自己实现
		memset memcmp memcpy memmove 自己实现 memset #include <stdio.h> #include <memory.h> #include ... 
- memcpy memmove区别和实现
		memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ... 
- 自己实现内存操作函数memset(),memcmp(),memcpy(),memmove()
		1.memset()内存设置函数(初始化) void *my_memset(void* dest, int c, size_t count) { assert(dest != NULL); char ... 
- 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset
		我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ... 
- C的memset,memcpy,strcpy 的区别 及memset memcpy memmove源码
		extern void *memcpy(void *dest,void *src,unsigned int count);#include <string.h> 功能:由src所指内存 ... 
- 一些关于memcpy  memmove函数的区别,和模拟实现
		memcpy: 它是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. 函数原型:void* memcp ... 
- strcpy和memcpy,memmove函数的区别
		strcpy和memcpy的区别 strcpy和memcpy都是标准C库函数,它们有下面的特点. strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制 ... 
- strcpy,memcpy,memmove和内存重叠分析
		一:strcpy函数用法和实现: /* GNU-C中的实现(节选): */ char* strcpy(char *d, const char *s) { char *r=d; while((*d++= ... 
随机推荐
- Protobuf入门实例
			Protobuf是一个灵活.高效.结构化的数据序列化框架,相比于XML等传统的序列化工具, 它更小.更快.更简单.Protobuf支持数据结构化一次就可以到处使用,甚至是跨语言使用,通过代码生成工具可 ... 
- tflearn 中文汉字识别模型试验汇总
			def get_model(width, height, classes=40): # TODO, modify model # Building 'VGG Network' network = in ... 
- 怎样安装CentOS 6.6之三:磁盘分区的划分和修改
			安装 CentOS(或Linux)系统,最难的就是磁盘分区.磁盘分区需要根据自己的实际使用需要来规划,以达到最优的效果. 工具/原料 CentOS 6.6 安装包 VMware 虚拟机 一.划分方 ... 
- VirtualBox下安装ubuntu图文教程以及软件安装
			一. 下载安装VirtualBox 官网下载VirtualBox,目前版本:VirtualBox 5.1.8 for Windows hosts x86/amd64 下载好了安装VirtualBox, ... 
- TCP连接状态变化
			TCP连接状态变化 参考文章:TCP连接的状态详解以及故障排查 TCP建立连接--三次握手 CLOSED:起始状态,无任何连接. LISTEN:服务端建立socket之后需要listen进入LISTE ... 
- mongodb "$"的作用
			{ "_id": ObjectId("58e48e32830f398e8f401a95"), "_class": "com.ydd ... 
- 1.18-1.21 Oozie Coordinator调度
			一.时区问题 1.修改系统时区 ## [root@hadoop-senior hadoop-2.5.0-cdh5.3.6]# rm -rf /etc/localtime [root@hadoop-se ... 
- Multipath TCP on iOS11 : A closer look at the TCP Options(转)
			Multipath TCP uses a variety of TCP options to use different paths simultaneously. Several Multipath ... 
- linux中用管道实现兄弟进程通信
			1 使用fork函数创建两个子进程.在第一个子进程中发送消息到第二个子进程,第二个子进程都出来并处理. 2 在父进程中,不适用管道通信,所以什么不需要做直接关闭勒管道的两端 3 代码实现 #inclu ... 
- Docker 网络模型之 macvlan 详解,图解,实验完整
			本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 上一篇文章我们 ... 
