百科问答小站 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届学术年会摘要集-第一分会:物理化学前沿 - 论文检索系统 - 中国化学会

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

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




  

相关话题

  为什么中国的计算机教育这么落后? 
  知乎上有哪些著名的“计算机科学”领域的“民科”? 
  怎么找到姚班或者ACM班或者其他高校计算机巨强的男生做男朋友呀? 
  如何反驳「没有乔布斯就没有今天的个人计算机」的观点? 
  为何早期版本Windows NT需要ctrl alt delete三键才可以登录? 
  电脑自己装跟买整机分别有什么好处? 
  为什么开源软件往往都支持Linux/Mac/Windows,而闭源软件往往只支持Win和Mac? 
  香农的信息论究竟牛在哪里? 
  Linux 为什么还要坚持使用宏内核? 
  想问r7 5800h笔记本可以撑多久?16g内存可以撑多久,本人今年大学学计算机到硕士算7年。够吗? 

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





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