asp模版网站如何做优化科技论文发表网

diannao/2026/1/22 21:45:58/文章来源:
asp模版网站如何做优化,科技论文发表网,职业生涯规划大赛ppt,如何优化网络以下有三个版本的memcpy#xff0c;对于版本3#xff0c;很多人都很熟悉#xff0c;它很经典#xff0c;很多人面试都写这个#xff0c;可是我不得不说一句#xff0c;对于类似的问题#xff0c;最好的回答有两个#xff1a;一是调用c库#xff0c;二是使用汇编。用这… 以下有三个版本的memcpy对于版本3很多人都很熟悉它很经典很多人面试都写这个可是我不得不说一句对于类似的问题最好的回答有两个一是调用c库二是使用汇编。用这一类的问题来考察应聘者的c语言能力真的很菜如果真的要考察c语言能力还不如给几个ifswitch-casefor语句呢。 版本1.linux内核中的实现其实glibc也是如此实现的省略了不少内容真正的实现很巧妙将n个字节分为了三部分(前导字节-对齐到页面页面后续字节-页面对齐后的游离字节)进行分块拷贝(linux内核是绝对不会卖弄c语言的基本的底层函数最终为了高效大多数都用汇编) char *memcpy1(char *to, char *from, size_t n) {     long esi, edi;     int ecx;     esi (long)from;     edi (long)to;     asm volatile(rep ; movsl         : c (ecx), D (edi), S (esi)         : 0 (n / 4), 1 (edi), 2 (esi)         : memory         );     return to; } 版本2.memcpy2为经典的C面试者写法 char *memcpy2(char *dest, char *src, size_t n) {         int i 0;     while (i n)     {         dest[i] src[i];         i ;     }     return dest; } 版本3.glibc的写法 ... 仅仅这几个memcpy版本如何确定哪个更高效呢以下是一个测试的例子请看例子1。 例子1 #include stdlib.h #include stdio.h #include time.h #define COUNTS 6000000 long long getcyclenow() {     unsigned int h, l;     long long bs, cc;     asm(rdtsc /n/t);     asm(movl %%eax, %0/n/t:g(l));     asm(movl %%edx, %0/n/t:g(h));     bs h;     cc (bs 32)|l;     return cc; } int main(int argc, char **argv) {     time_t st0, st1, st2, st3;     long long l0, l1, l2, l3;     int i 0;     char *src (char *)calloc(1, 109);     strcpy(src, iiiiabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz);     char *dest0 (char *)calloc(1, 109);     char *dest1 (char *)calloc(1, 109);     char *dest2 (char *)calloc(1, 109);     l0 getcyclenow();        dest0 memcpy(dest0, src, 108);     l1 getcyclenow();        dest2 memcpy2(dest2, src, 108);     l2 getcyclenow();        dest1 memcpy1(dest1, src, 108);     l3 getcyclenow();        printf(%X/t%X/t%X/n, l1-l0, l2-l1, l3-l2);         memset(dest0, 0, 109);     memset(dest1, 0, 109);     memset(dest2, 0, 109);     st0 time(NULL);     for (i 0; i COUNTS; i)         dest0 memcpy(dest0, src, 108);     st1 time(NULL);     for (i 0; i COUNTS; i)         dest2 memcpy2(dest2, src, 108);     st2 time(NULL);     for (i 0; i COUNTS; i)         dest1 memcpy1(dest1, src, 108);     st3 time(NULL);     printf(t0:%f, t1:%f, %f/n, difftime(st1, st0), difftime(st2, st1), difftime(st3, st2)); /*     memset(dest0, 0, 109);     memset(dest1, 0, 109);     memset(dest2, 0, 109);         l0 getcyclenow();        dest0 memcpy(dest0, src, 108);     l1 getcyclenow();        dest2 memcpy2(dest2, src, 108);     l2 getcyclenow();        dest1 memcpy1(dest1, src, 108);     l3 getcyclenow();        printf(%X/t%X/t%X/n, l1-l0, l2-l1, l3-l2); */     return 0; } 执行这个程序看第一个printf输出发现memcpy是最慢的而汇编写的memcpy1是最快的而经典的面试写法memcpy2位居中间可是看c库的memcpy源码或者其反汇编代码它也是使用了rep ; movsX指令那为什么它慢呢考虑到了数据缓存问题将memcpy和memcpy1以及memcpy2的调用互换了位置仍然是c库的memcpy最慢这就给了很多涉业不久的毕业生十足的理由继续往笔试卷上写memcpy2之类的。附带一句后面的for循环的COUNTS次测速为了得到一个统计值这次发现memcpy2最慢memcpy比memcpy1慢一点点但是都比memcpy2快很多这名显与通过rdtsc测试出来的结果不对应于是肯定哪里出了问题。      实际上这是cpu指令预取和指令cache以及缺页引起的而和c库以及c库实现的memcpy没有关系要知道c库大家都在用不会有如此明显的性能问题的再者说随便懂点cpu知识和汇编的人都知道memcpy2是最不可取的因为它里面有大量的条件判断和条件跳转这对于cpu的流水线是很不利的并且通过c语言语义上语句实现拷贝增加了指令数从而也就是增加了执行时间x86处理器猛就猛在其是从cisc演变过来的包含了大量的指令于是movsX加repeat前缀肯定是不二的选择啦。当第一次调用memcpy的时候cpu不得不从其所在的“地址”处将指令取到cpu然后就cache到那里了除非越来越多的别的指令将它冲掉(flush)它就一直在那里。      另外tlb也是一个重要的因素tlb缓存了虚拟地址和物理地址的映射在cpu用虚拟地址访存时需要通过mmu得到物理地址tlb可以缓存这个映射从而以后不再需要查询页表直接从tlb中得到物理地址。对于指令的寻址cpu也是按照虚拟地址来的第一次访问时要完全查找页表并且还可能缺页接下来从最慢的磁盘将数据读到次慢的内存然后将物理地址-虚拟地址的映射读入tlb指令进入icache因此接下来的调用就会很快了。有个问题需要解释c库的函数不是一直cache在内存中的吗是的但是第一它没有cache在处理器中第二它虽然缓存在了内存但是对于当前task却不一定建立了页表项而处理器dcache/icache(数据缓存/指令缓存)是通过物理地址寻址的(而tlb是虚拟地址寻址的)因此会导致两个不命中cpu cache(icache/dcache/tlb)不命中和页表项不命中然后发生缺页内核准备读磁盘之前首先要看一下它是否在内存中如果在的话直接建立页表项映射就可以了对于c库的函数一般是在内存的(前提是内存足够大)因此第一次调用c库函数只会有缺页-建立页表项的开销而大多数情况下不会有读磁盘的开销。      下面通过例子2分析问题到底出在哪里 例子2 #include stdlib.h #include stdio.h #define ALIGN  0X800 int test() {     return 1; } void __attribute__ ((aligned (ALIGN))) stub() {     return; } long long getcycle() {     unsigned int h, l;     long long bs, cc;     asm(rdtsc /n/t);     asm(movl %%eax, %0/n/t:g(l));     asm(movl %%edx, %0/n/t:g(h));     bs h;     cc (bs 32)|l;     return cc; } int main(int argc, char **argv) {     long long t1, t2, t3, t4;     printf(%p/t%p/t%p/n, test, stub, main);     t1 getcycle();     test();     t2 getcycle();     test();     t3 getcycle();     test();     t4 getcycle();     printf(%X/t%X/t%X/n, t2-t1, t3-t2, t4-t3);     printf(%p/t%p/t%p/n, getcycle, test, main);     return 0; } stub函数设置了aligned这个attribute为了在test函数和main之间制造一点“距离”(用nop指令填充)这样的话第一cpu的指令预取(instruction prefetch)就取不到了毕竟cpu的指令缓存是有限的第二执行main之前main函数一定要映射进页表项由于mmu按页大小(4096字节)映射拉开一定距离就不会让test也映射进入在下一个例子中我们会调整这个距离来表明缺页对执行性能的影响。控制ALIGN的值使得test函数和main的距离变化当ALIGN很小的时候test和main离的很近(小于一个页面且在同一页面)cpu可能会根据局部性原理加载main的时候将test的指令取入cache并且由于test和main在一个页面test也会进入内存且建立页表映射从而tlb中也会有test的物理地址然而如果ALIGN很大比如是0x10000这样test和main很远cpu既取不到test的指令又不会建立页表映射在第一次执行test的时候会缺页会花费很多时间以下讨论不再考虑cpu预取仅考虑缺页和cpu的icache也不再考虑tlb因为在访问一组连续地址(页面)的第一个字节时地址映射信息就会进入tlb以下一个页面内的连续访问几乎都会命中1个字节带来的优势对比一个页面字节来讲效果不容易表现出来(测试不容易)。因此在ALIGN为0x10000的时候执行结果如下 b36     3f      38 0x450017        0x420006        0x450045 第一次和第二次调用test足有40多倍的延迟。由于指令已经cache了第二次和第三次执行就很快了。为了证明是缺页的的影响很大把getcycle的定义放到test之前 long long getcycle() {     ... } int test() {     return 1; } void __attribute__ ((aligned (ALIGN))) stub() {     return; } 在执行test之前要先执行一个t1 getcycle();该调用会触发getcycle缺页由于getcycle和test在同一页面也就是说会建立test的页表映射执行结果如下 3f      38      3f 0x420000        0x420034        0x450017 虽然main和test离的仍然很远然而getcycle和test很近在调用getcycle的时候会建立页表项因此速度加快很多以后就从指令缓存icache中取指令为了再次证实这个事情且不影响getcycle的执行将getcycle放回原位然后在test之前放一个stub0然后在第一个调用getcycle之前调用stub0然后看结果三次执行test的时间仍然很接近。看一下linux的do_page_fault的代码的确很多这些都要算在t2-t1中怪不得缺页情形下多了那么多的时间。      因此前一个例子中c库的memcpy慢的原因就找到了将例子1中main函数最后的注释放开再次编译执行(-O0参数不优化前面的例子2也要这样编译)发现memcpy1仍然是最快的而c库的memcpy位居第二和memcpy1相差不多而面试版本的memcpy2最慢。接下来看例子3展示缺页的影响。 例子3 #include stdlib.h #include stdio.h #include string.h #define ALIGN_test  0X800 #define ALIGN_main  0X800 long long getcycle() {         unsigned int h, l;         long long bs, cc;         asm(rdtsc /n/t);         asm(movl %%eax, %0/n/t:g(l));         asm(movl %%edx, %0/n/t:g(h));         bs h;         cc (bs 32)|l;         return cc; } void  __attribute__ ((aligned (0x10000))) stub0()  //为了让test和main分布在两个页面中 {         return; } int __attribute__ ((aligned (ALIGN_test)))  test(char *buf) {    //增加一些代码让它像真正的函数。要使用-O0编译         int i 2, j3;         if (buf[0] i)                 j 3;         for (j; j 10; i jbuf[i])                 j buf[j];         if (buf[0] i)                 j 3;         for (j; j 10; i jbuf[i])                 j buf[j];         if (buf[0] i)                 j 3;         for (j; j 10; i jbuf[i])                 j buf[j];         return i*j; }; int __attribute__ ((aligned (ALIGN_main))) main(int argc, char **argv) {         long long t1, t2, t3, t4;         char b[25] {0};         t1 getcycle();         memcpy(b, ddddd, 5);         t2 getcycle();         memcpy(b, ddddd, 5);         t3 getcycle();         memcpy(b, ddddd, 5);         t4 getcycle();         printf(%llx/t%llx/t%llx/n, t2-t1, t3-t2, t4-t3);         t1 getcycle();         test(ddddd/n);         t2 getcycle();         test(ddddd/n);         t3 getcycle();         test(ddddd/n);         t4 getcycle();         printf(%llx/t%llx/t%llx/n, t2-t1, t3-t2, t4-t3);         printf(%p/t%p/t%p/n, getcycle, printf2, main); } ALIGN_main和ALIGN_test均为0x800的情况下上述的代码将把test和main分布在两个页面中间隔0x800执行main时并不会为test建立映射因此第一次执行test函数时将会慢很多如果将ALIGN_main和ALIGN_test分别调整为0x800和0x1000那么test和main就会分布在同一个页面第一次执行test明显会快很多这就是缺页带来的影响可见页面调入实在太耗时了。在结束rdtsc指令的第一个影响因素之前再看一个例子理解一下共享库的作用。 例子4 share.h: int test1(); share.c int test1() {         return 3; } test1.c: #include stdlib.h #include stdio.h #include share.h long long getcycle() {         unsigned int h, l;         long long bs, cc;         long long interval, start, end;         asm(rdtsc /n/t);         asm(movl %%eax, %0/n/t:g(l));         asm(movl %%edx, %0/n/t:g(h));         bs h;         cc (bs 32)|l;         return cc; } int main(int argc, char **argv) {         time_t st0, st1, st2, st3;         long long l0, l1, l2, l3;         l0 getcycle();         test1();         l1 getcycle();         test1();         l2 getcycle();         test1();         l3 getcycle();         printf(%llx/t%llx/t%llx/n, l1-l0, l2-l1, l3-l2); } test2.c: #include stdlib.h #include stdio.h #include shar.h int main(int argc, char **argv) {         while(1) {                 test1();         } } 编译 gcc -fPIC -shared share.c -o libshare.so -O0 gcc test1.c -o test1 -L. -lshare gcc test2.c -o test2 -L. -lshare 1.连续执行test1 28b     46      3f 2.执行sysctl -w vm.drop_caches3后执行一次test1 391     54      46 3.在另一tty上执行test2然后执行test1 29a     46      38 4.在另一tty上执行test2执行sysctl -w vm.drop_caches3后执行test1 2c8     46      38 测试1说明第一次执行test1函数时缺页建立页表映射消耗大量时间连续执行后即使test1退出linux也可能将so缓存在了内存不再需要读磁盘因此得到了一个大致0x28b的数值测试2由于刷新了文件缓存缺页时需要读磁盘时间消耗明显增加测试3和测试1不相上下测试4并没有重现测试2的噩梦因此test2在循环执行中即使刷新了磁盘缓存test2也会将libshare.so读入磁盘由于libshare.so是共享的因此test1在第一次执行test1函数时只需要建立页面映射即可不必再读磁盘了这就是共享库的好处。      知道了cache和缺页带来的影响rdtsc就可以无忧得使用了吗不是这样的如果getcycle包围的待测试代码本身执行时间过长或者导致了进程调度那么两个getcycle调用的差值并不是真正的执行时间比如 t1 getcycle(); test() //很长可能会sleep t2 getcycle(); 如此一来t2-t1可能会把其它进程执行的时间都算上因为rdtsc获得的是cpu全局的嘀嗒信息而我们需要测试的执行时间是基于本进程的统计时间。因此实际上我们是不能信任rdtsc测试出来的结果的。哪一次在test()执行过程中发生调度几乎是用户态决定不了的(除非设置实时进程优先级并且没有IO)。 总结 1.编写代码时主要的调用函数要尽量紧凑的放在一个页面中注意向物理页面起始地址对齐不要离的太远这样可以提高执行效率。 2.使用共享库虽然可能因此增加几条指令(比如got机制的代价)然而却省去了很多缺页时读磁盘的开销。 3.测量长函数执行一次的时间不要相信rdtsc因此中间如果发生调度别的进程时间也会计算进去rdtsc是全局的。 4.挖掘机器的特性在指令级别寻找办法不要太迷恋c语言。 转载于:https://blog.51cto.com/dog250/1271087

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/89166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

装修网站论坛做cms网站

导读:农历新年将至,祝福的话汇成千言万语都寄托在贺卡之中,也许今年你受到了很多的挫折,又或者是顺顺利利度过了一年。但不管怎么样,不管是哭与笑,人生的年轮都已经转过了一圈。我们唯有继续向前走,不要回头,未来的自己取决于现在的自己。有时候一句不经意的问候,一句…

网站建设宣传视频教程绍兴网站优化

前言:生产linux部署的zookeeper,执行启动脚本后,还是无法使用,故进行重启排查 在zookeeper的bin目录下执行 ./zkServer.sh start-foreground 可实时查看启动日志排查问题 根据上面的日志可以看出,是zoo.cfg配置文件里…

wordpress网站的cdn怎么设置免费自己做网站手机软件

webm是一个开放、免费的媒体文件格式。WebM影片格式是以Matroska(即MKV)容器格式为基础开发的新容器格式,里面包括了VP8影片轨和Ogg Vorbis音轨;其中Google将其拥有的VP8视频编码技术以类似BSD授权开源,而Ogg Vorbis本…

省市建设类网站链接网页制作与网站建设初学者必看教程

在Docker中进行MySQL数据迁移通常涉及将数据从一个MySQL容器导出&#xff0c;并将其导入到另一个容器或主机上的MySQL实例中。以下是一般步骤&#xff1a; 步骤 1: 在源 MySQL 容器中导出数据 进入源 MySQL 容器&#xff1a; docker exec -it <source_mysql_container_name…

网站优化软件推荐做算命网站挣钱么

在上一篇博客&#xff1a;C#曲线分析平台的制作&#xff08;三&#xff0c;三层构架echarts显示&#xff09;中已经完成了后台的三层构架的简单搭建&#xff0c;为实现后面的拓展应用开发和review 改写提供了方便。而在曲线分析平台中&#xff0c;往往有要求时间轴联动功能&…

网站参数保险做的好的网站有哪些内容

在日常生活和工作中&#xff0c;我们经常会遇到需要从Word文档中提取图片的情况。无论是为了单独保存这些图片&#xff0c;还是为了在其他地方使用它们&#xff0c;一键提取Word中的图片都是一个非常实用的技能。提取Word文件中的图片并不是一件复杂的事情&#xff0c;只要掌握…

西安网站建设网站法律咨询免费律师在线咨询

将npm的下载源恢复为默认的官方源&#xff0c;命令如下&#xff1a; npm config set registry https://registry.npmjs.org淘宝官方提供的最新的配置淘宝镜像的方法&#xff0c;命令如下&#xff1a; npm config set registry https://registry.npmmirror.com也可以查看是否修改…

东营北京网站建设多媒体设计与制作毕业设计

win11配置Mask DINO踩坑记录 1 准备工作2 创建python环境和安装detectron22.1 安装前提2.2 安装流程2.2.1 cl.exe的错误2.2.2 SetuptoolsDeprecationWarning的错误 3 MaskDINO运行3.1 运行demo 前情提要&#xff1a;需要复现Mask DINO&#xff0c;但是实验室没有Linux的电脑&am…

网站建设学习浩森宇特霞浦建设局网站

二、MSTPEth-trunk 实验拓扑实验需求及解法 实验拓扑 实验需求及解法 //1.如图所示&#xff0c;配置设备名称和 IP 地址。 //2.在 SW1 与 SW2 之间配置链路聚合协议 LACP&#xff0c;完成以下需求&#xff1a; //2.1 SW1 作为主动端&#xff0c;设置系统优先级为最高。 [SW1]l…

旅游网站排名榜php外贸网站源码

我们都知道&#xff0c;JDK 其实给我们提供了很多很多 Java 开发者已经写好的现成的类&#xff0c;他们其实都可以理解成工具类&#xff0c;比如我们常见的集合类&#xff0c;日期相关的类&#xff0c;数学相关的类等等&#xff0c;有了这些工具类&#xff0c;你会发现它能很大…

汕头网站制作全过程佛山企业网站设计公司

三、2023年12月GESP Python三级编程题 【三级编程题1】 【试题名称】&#xff1a;小猫分鱼 【问题描述】 海滩上有一堆鱼&#xff0c;N只小猫来分。第一只小猫把这堆鱼平均分为N份&#xff0c;多了i<N条鱼&#xff0c;这只小猫把多的i条鱼扔入海中&#xff0c;拿走了一份…

珠海建设集团网站首页网络工程公司的业务

简单查询insert添加insert可以使用数据库支持的自动生成主键策略&#xff0c;设置useGeneratedKeys”true”&#xff0c;然后把keyProperty 设成对应的列&#xff0c;就搞定了。比如说上面的StudentEntity 使用auto-generated 为id 列生成主键.还可以使用selectKey元素。下面例…

成都微网站开发动态电商网站怎么做

选本必看--笔记本主流cpu参数大全现在本本的处理器种类真的太多了&#xff0c;绝对足够让人眼花缭乱的&#xff0c;各式各样的CPU核心、外频、缓存、接口、电压、制作工艺等等&#xff0c;多到让人疯狂&#xff0c;很少认能够对此了如执掌的。这次我们归纳了所有主流的本本处理…

wordpress自适应建站wordpress 指定

Spark事件总线机制 采用Spark2.11源码&#xff0c;以下类或方法被DeveloperApi注解额部分&#xff0c;可能出现不同版本不同实现的情况。 Spark中的事件总线用于接受事件并提交到对应的监听器中。事件总线在Spark应用启动时&#xff0c;会在SparkContext中激活spark运行的事件总…

一个公司优化需要做多少个网站前端开发和后端开发哪个好些

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 企业活动发布会邀请媒体报道具有多种好处与优势&#xff0c;这些都有助于提升企业的知名度、形象和影响力。以下是一些主要的好处与优势&#xff1a; 提升品牌知名度&#xff1a;媒体报道…

工会网站建设可以wordpress for sae 4.3

​在使用jmeter进行接口测试时&#xff0c;我们难免会遇到需要从上下文中获取测试数据的情况&#xff0c;这个时候就需要引入变量了。 定义变量 添加->配置元件->用户自定义的变量 添加->配置元件->CSV 数据文件设置 变量的调用方式&#xff1a;${变量名} 变量的…

齐齐哈尔住房和城乡建设局网站课程网站如何建设方案

LED流水灯 循环左移右移函数 crol(a,b):循环左移函数&#xff0c;a是左移的值&#xff0c;b是左移的位数。包含在instrins.h库函数里面。 cror(a,b):循环右移函数&#xff0c;a是右移的值&#xff0c;b是右移的位数。包含在instrins.h库函数里面。 实验代码 #include "…

网站建设投标书报价表湘潭网站建设厦门网站制作

IP地址定位能够精确到的位置级别取决于多种因素&#xff0c;包括IP地址的分配方式、数据库的质量和更新频率、用户的移动性等。一般而言&#xff0c;IP地址定位可以精确到市级&#xff0c;甚至可以达到街道级别 https://www.ip66.net/?utm-sourceLJ&utm-keyword?1146 但需…