百科问答小站 logo
百科问答小站 font logo



为什么本人笔记本使用 Linux 和 Windows 编译速度完全不一样?(尤其是arduino)? 第1页

  

user avatar   bei-ji-85 网友的相关建议: 
      

跟安全软件无关,哪怕把所有安全软件都关了,Windows也是一样慢,就是文件系统的问题。

先放结论:在缓存没有耗尽的情况下,Linux的小文件访问性能要远远高于Windows,这是Windows文件系统和整个操作系统缓存策略的问题。

各种性能测试软件,往往都是在关闭缓存或者耗尽缓存以后才开始统计的,所以性能测试上NTFS跟EXT4之间看不出明显的差异。

一些比较直观的证据:

NTFS-3G在Linux上的性能是要好于NTFS在Windows上的性能的(同样的硬件);
批量删除小文件(使用命令行),EXT4的性能远远高于NTFS(同样硬件);
从主机往U盘上写入小文件(1M以内),Linux实际上是立即返回(只写到缓存里),Windows则是真正写到了盘里,拔盘的话可以看到Linux的盘上没有任何数据。

注意,这里只强调用户体验的性能,而不是测试跑分。Linux是有可能丢失更多的文件,但丢失文件跟性能话题无关。

有人宁可相信自己的直觉,也不肯动手做一下实验,在这个回答的最后有一段代码测试,有兴趣的可以在自己机器上做一下实验



放一段XP泄漏的NTFS代码,在DriverEntry里,根据系统内存大小来确定一些cache之类的大小:

           switch ( MmQuerySystemSize() ) {      case MmSmallSystem:          NtfsMcbHighWaterMark = 1000;         NtfsMcbLowWaterMark = 500;         NtfsMcbCurrentLevel = 0;         break;      case MmMediumSystem:          NtfsMcbHighWaterMark = 4000;         NtfsMcbLowWaterMark = 2000;         NtfsMcbCurrentLevel = 0;         break;      case MmLargeSystem:     default:          NtfsMcbHighWaterMark = 16000;         NtfsMcbLowWaterMark = 8000;         NtfsMcbCurrentLevel = 0;         break;     }     

通过那个MmQuerySystemSize函数,来决定用多大的cache,但是看看MmQuerySystemSize函数的代码实现里有一段注释:

       MM_SYSTEMSIZE MmQuerySystemSize(     VOID     ) {     //     // 12Mb  is small     // 12-19 is medium     // > 19 is large     //     return MmSystemSize; }     

19M以上就算大内存了,可见Windows对内存的使用是多么保守。另外NtfsInitializeNtfsData里也可以看到cache的大小,在如今内存上GB的时代,Windows的文件系统缓存还停留在十几MB的范围,这种情况下你不能指望Windows的文件系统性能有多好。

特别提醒:19M指的是系统总内存大于19M,就认为是大内存。当然了,这段注释可能不准,有兴趣的可以看这里:

               if (MmNumberOfPhysicalPages >= ((32*1024*1024)/PAGE_SIZE)) {              //             // If we are on a workstation, 32Mb and above are considered             // large systems.             //              if (MmProductType == 0x00690057) {                 MmSystemSize = MmLargeSystem;              }             else {                  //                 // For servers, 64Mb and greater is a large system                 //                  if (MmNumberOfPhysicalPages >= ((64*1024*1024)/PAGE_SIZE)) {                     MmSystemSize = MmLargeSystem;                 }             }     

相比之下,Linux上来就能先保留一半物理内存作为整体的缓存使用,所以在操作的文件比较少的情况下,Windows和Linux的文件系统差距非常明显。只有当缓存全部耗尽了,两者性能才会比较接近(当然了,小文件性能,Windows还是一样的差,系统框架设计的问题)。

没有XP源码的,可以去WRK上看FAT的源码。FAT32驱动,在大内存配置下,最多的延迟关闭的文件数量是256个,这样的文件系统,性能要是好了才奇怪。


有人说,我这个是XP的代码,现在WIN10都不这样了,验证的方法很简单,找WIN10的驱动反汇编一下:

FAT对应的驱动是FASTFAT.SYS:

FatMaxDelayedCloseCount最大值仍然是256

对于NTFS,代码变化有点大,就贴一段汇编:

       INIT:00000001C0295321                 mov     edx, cs:dword_1C00951DC INIT:00000001C0295327                 imul    eax, r14d, 3E80h INIT:00000001C029532E                 shl     rdx, 3 INIT:00000001C0295332                 mov     cs:NtfsMcbCurrentLevel, ebx INIT:00000001C0295338                 mov     cs:NtfsMcbHighWaterMark, eax INIT:00000001C029533E                 imul    eax, r14d, 1F40h INIT:00000001C0295345                 mov     cs:NtfsMcbLowWaterMark, eax INIT:00000001C029534B                 mov     eax, 0FFFFFFFFh INIT:00000001C0295350                 cmp     rdx, rax INIT:00000001C0295353                 jbe     short loc_1C029537B INIT:00000001C0295355                 xor     r9d, r9d     

关键值:imul eax, r14d, 3E80h,0x3e80 ==> 16000,NtfsMcbHighWaterMark跟XP时代不变。(R14D默认值是1,代码比较绕,就不全贴出来了)。

这个值,微软的文档写的是允许改的,可以改成2:

2的话也就是16000*2,也没大多少。

评论里 @轻语碎雷 说NTFS的代码改过,跟XP时代确实改过,但本质上还是拿16000乘以注册表项HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlFileSystem下的:NtfsMemoryUsage,如果这个值是0,则默认是乘以1,所以本质上跟XP没什么差别。

反汇编WIN10的NTFS.SYS即可得到相应的结论。

我不知道为什么有人容不得说Windows文件系统的缺陷。Windows文件系统(包括IO框架)有性能问题是实际存在的,这个问题从NT时代一开始就有,文件系统里fastio这些接口本质上都是为了解决一部分文件系统的性能问题。

Windows文件系统另一个相似的问题:


另外,不怕丢数据的可以做一个实验,在Linux上写NTFS盘,看看性能怎么样,反正我试过的结果是比Windows自己的NTFS还要快一些。


Windows文件系统(含块设备驱动)的cache设计整体上是偏向于保守的,上面的例子只是说明文件系统的缓存设计,实际上包括块设备驱动这一层,Windows也一样存在大量保守的设计。由于兼容性的问题,Windows并不轻易更改这方面的设计,因此,在系统有大量内存的情况下,Windows的文件系统性能确实不如Linux。

Linux的激进的缓存策略并不一定永远都是好用的,比如Linux上U盘更容易丢失数据,Windows针对U盘的写策略默认是write-through的,写完拔盘很少丢文件。

企业客户们使用Windows,更重视的是Windows的兼容性以及易用性。当然,Windows的游戏(图形)性能确实出众。

任何系统都有优点和缺点,不管是Windows还是Linux。


有人不相信Windows文件系统有多慢,动手写一段代码就好了:

       #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #ifndef _WIN32 #include <unistd.h> #endif  int main(int argc, char * argv[]) {     FILE* fp;     clock_t st, ed;     int count;      char fname[256] = { 0 };     if (argc != 2)     {         printf("Usage %s <count>
", argv[0]);         return -1;     }     count = atoi(argv[1]);     st = clock();     for (int i = 0; i < count; i++)     {         sprintf(fname, "test%d", i);         fp = fopen(fname, "wb");          fwrite(fname, sizeof(fname), 1, fp);         fclose(fp);     }      for (int i = 0; i < count; i++)     {         sprintf(fname, "test%d", i); #ifdef _WIN32         _unlink(fname); #else         unlink(fname); #endif     }     ed = clock();     printf("Clock = %d, %d, %d, %d, %d", ed - st, st, ed, CLOCKS_PER_SEC, (ed - st) / CLOCKS_PER_SEC);     return 0; }     

以上代码,在我的电脑上,参数传入10000(也就是创建、删除10000个小文件)Windows运行结果如下:

Clock = 6053, 0, 6053, 1000, 6

耗时6秒多。

在同样的环境下,用virtualbox虚拟机(fedora33)编译运行,结果如下

Clock = 642972, 2298, 645270, 1000000, 0

也就是说Windows上用了6秒,Linux上用了0.6秒,整整差了10倍,而我这个环境里,Linux是虚拟机。自己去判断一下真实的Linux比Windows能快多少。测试文件越少,差距越大。(注:不同机器上测得的数据差别很大,我拿到的最大的性能差距是:Windows:14秒、Linux虚拟机:0.4秒)

加上Windows上一些安全软件的影响,小文件操作性能差距100倍以上太正常了。

我相信,对于有些人来说,哪怕你把数据丢到他眼前,他还会找各种理由

实际编译肯定没10000个文件这么多;
你的测试也没达到2分钟那么慢;
你这个盘太慢了;
你肯定没关杀毒软件;
……

对于这些评论,我想说,你们说的都对,Windows的文件系统是最快的文件系统,肯定是用户用的不对。


user avatar   qinlili233 网友的相关建议: 
      

这个问题问得很好啊,我的建议是看今年年会的摘要集:

中国化学会第32届学术年会 - 论文检索系统 - 中国化学会

可以看到有很多分会,不过计算化学分布得比较散,夹杂在各个分会中。各分会的主题可以从这里找到,可能相关的包括:

有一些主题是理论计算夹杂着实验的,还需要仔细辨别。回到摘要集,以第一分会为例:

中国化学会第32届学术年会摘要集-第一分会:物理化学前沿 - 论文检索系统 - 中国化学会

可以看到题目和单位全都标出来了,而且还可以下载。

显然,能找到相关方向的摘要的单位,就是开设了相关方向的院校,甚至还能精确到具体的某个课题组。




  

相关话题

  计算机中,假设键盘同时按下两个键,会优先生效哪一个? 
  超威半导体(AMD)的超线程技术和英特尔(Intel)的超线程技术有差别吗? 
  如何看待中国人很多使用盗版 Windows 系统? 
  解压文件的速度瓶颈在cpu还是硬盘速度? 
  为何目前有eGPU(外接显卡), 而没有eCPU(外接中央处理器)? 
  配置管理Linux高性能计算集群需要从何开始? 
  游戏开发的编程算不算是 IT 行业中难度最大的? 
  Windows 系统的硬件利用率是不是很差? 
  windows有更方便的IDE进行开发, 为什么互联网公司的服务器还是用linux? 
  如何解决SolidWorks运行很卡? 

前一个讨论
当两个CPU核心要求读写同一内存地址时,其后果是未定义行为吗?
下一个讨论
可以预先将 X86 平台机器码译码到 micro operations 来解决 X86 译码效率低吗?





© 2024-11-27 - tinynew.org. All Rights Reserved.
© 2024-11-27 - tinynew.org. 保留所有权利