找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: 2011yaya2007777

支持含有碎片的文件仿真

   火... [复制链接]
发表于 2014-12-22 13:33:42 | 显示全部楼层
chenall 发表于 2014-12-22 11:51
我也是试了没有找到原因,而且我这里测试速度没有多大变化呀.

你可以测试一下这三个重新编译的(对应那一 ...

grldr0.4.5c-a6bfd1a: 11秒----慢
grldr0.4.5c-a6bfd1a.png
回复

使用道具 举报

发表于 2014-12-22 13:36:44 | 显示全部楼层
chenall 发表于 2014-12-22 11:51
我也是试了没有找到原因,而且我这里测试速度没有多大变化呀.

你可以测试一下这三个重新编译的(对应那一 ...

grldr0.4.5c-a1cbe95: 11秒--慢
grldr0.4.5c-a1cbe95.png
回复

使用道具 举报

发表于 2014-12-22 13:42:54 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-22 13:44 编辑
chenall 发表于 2014-12-22 11:51
我也是试了没有找到原因,而且我这里测试速度没有多大变化呀.

你可以测试一下这三个重新编译的(对应那一 ...


》》而且我这里测试速度没有多大变化呀.
需要测试的分区足够大,才能体现这种速度差异。
找个>=10G的系统分区(win7,win8更好)试试。
回复

使用道具 举报

发表于 2014-12-22 14:31:56 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-22 14:35 编辑
不点 发表于 2014-12-22 10:44
该怎么办,由 chenall、yaya 来处理吧。这期间有至少两次改动,比较麻烦。其一,我看不出改动有任何毛病。 ...


下面是换台稍新店的笔记本电脑(大概11年的)
性能高点的SATA本地硬盘。
测试的是80G的win7X64分区。

因为分区是原来的8倍,但盘子性能好点,时间普遍是原来的5倍!
grldr046a120324.png
grldr046a120227.png
随大小而增长。这个不应该。看来主要是的算法问题。
是不是哪儿多了个和大小相关的循环。

grub0.45b2011714无法运行在该电脑上,无法测试。
回复

使用道具 举报

发表于 2014-12-22 16:07:22 | 显示全部楼层
那就是a6bfd1a这个版本开始出现的问题了..可是这个里面没有改动任何磁盘读写的代码,,不到找原因.

估计也是和编译有关,只能尽量查找原因了.

点评

找原因,比解决问题更复杂, 尤其是这种嵌入式开发。 (根据我的经验)我建议,(绕开原因)直接从前面那个正确的版本出发,编译环境什么都不改。 在一点一点地, 将后面版本的代码移过去,每次尽量少移,移一次  详情 回复 发表于 2014-12-22 17:11
回复

使用道具 举报

发表于 2014-12-22 16:26:04 | 显示全部楼层
恶心人的 gcc,给我们造成了很多的问题。

看来最可靠的是汇编了,这不太容易出错。

gcc 除了开发者失误的可能性以外,还可能遭到间谍的攻击了。

点评

》》gcc 除了开发者失误的可能性以外,还可能遭到间谍的攻击了。 免费的东西,也不要要求太高。 质量和稳定性可靠性,是银子对出来的。 在这个急剧变化的时代,尤其如此。 人家免费,没有收入。 很多工作没  详情 回复 发表于 2014-12-22 17:16
回复

使用道具 举报

发表于 2014-12-22 17:11:57 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-22 17:13 编辑
chenall 发表于 2014-12-22 16:07
那就是a6bfd1a这个版本开始出现的问题了..可是这个里面没有改动任何磁盘读写的代码,,不到找原因.

估计也 ...


找原因,比解决问题更复杂, 尤其是这种嵌入式开发(或者说和硬件打交道,什么稀奇,什么地方都会出现)。

(根据我的经验)我建议,(绕开原因)直接从前面那个正确的版本出发,编译环境什么都不改。
再一点一点地, 将后面版本的代码移过去,每次尽量少移,移一次,测试一下;直到重要的代码都移过去了,还是正确的。就行了。
(至于找原因,那是权当个人兴趣,有空才特地去找。 说不定上面“顺便”就找的差不多了)

点评

我一直都是这样做的,^_^.  详情 回复 发表于 2014-12-22 17:30
回复

使用道具 举报

发表于 2014-12-22 17:16:04 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-22 17:37 编辑
不点 发表于 2014-12-22 16:26
恶心人的 gcc,给我们造成了很多的问题。

看来最可靠的是汇编了,这不太容易出错。


》》gcc 除了开发者失误的可能性以外,还可能遭到间谍的攻击了。
免费的东西,也不要要求太高。

质量、稳定性和可靠性,是银子堆出来的。
况且gcc这么复杂的系统。
在这个急剧变化的时代,尤其如此。
人家免费,没有收入。
很多工作没有保证。



-----------
容易出问题,主要是使用环境引起的——嵌入式。
这种环境,大部分编译器都会出问题。

最容易出的问题是堆栈溢出。这个时候非常奇怪,换个(逻辑完全等效的)写法问题就没了。

我用摩托诺拉的编译器,也是这样,奇奇怪怪。 一个简单的整数除法,竟然会出问题,看代码根本看不出问题——代码逻辑根本没错。
最后反汇编才找出编译原因。


回复

使用道具 举报

发表于 2014-12-22 17:30:01 | 显示全部楼层
本帖最后由 chenall 于 2014-12-22 17:39 编辑
mdyblog 发表于 2014-12-22 17:11
找原因,比解决问题更复杂, 尤其是这种嵌入式开发(或者说和硬件打交道,什么稀奇,什么地方都会出现 ...


我一直都是这样做的,^_^.

目前初步定到到了cmdline.c文件的问题,具体什么代码的问题明天再继续.
回复

使用道具 举报

发表于 2014-12-23 11:16:54 | 显示全部楼层
这个问题看起来很难解决了.

-        char cmdline_buf[1500];
+        char *cmdline_buf = cmd_buffer;

使用 cmdline_buf[1500];时就是旧版的,不过当时记得就是由于这样子有问题(好像char cmdline_buf[N],这个N不能大于512否则会出错).

如果每一行命令都比较短则改成cmdline_buf[512];就行了(这个还是要变量扩展后的长度).不过目前加上变量扩展等,还有命令重定向等,超过512是很常见的.

不知还有没有其它的解决方法?我也尝试过用malloc来分配内存也是一样的效果,真的是很奇怪.

点评

char cmdline_buf[1500]; 这样会引起堆栈溢出。 嵌入式开发,最容易出现 堆栈溢出——内存太少,初始化的堆栈一般都很小,很容易溢出。 堆栈溢出,大部分马上死翘翘。 但是, 也有的 没有 马上死, 而是”改变  详情 回复 发表于 2014-12-23 13:31
回复

使用道具 举报

发表于 2014-12-23 11:56:45 | 显示全部楼层
找到地方,就是很大的成绩。

以后我们可以慢慢解决这一问题。

我觉得这些代码需要严格锤炼。

等我有时间的话,我会专门寻找代码的逻辑漏洞。

目前你可以暂时使用 char cmdline_buf[1500]; 看看会暴露出什么问题。

如果暴露出问题,再去解决。

回复

使用道具 举报

发表于 2014-12-23 13:31:33 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-23 13:52 编辑

chenall 发表于 2014-12-23 11:16
这个问题看起来很难解决了.

-        char cmdline_buf[1500];


char cmdline_buf[1500];
这样可能会引起堆栈溢出。
嵌入式开发,最容易出现 堆栈溢出——内存太少,初始化的堆栈一般都很小,很容易溢出。

堆栈溢出,大部分马上死翘翘。
但是, 也有的 没有 马上死, 而是”改变了不改改变的内存“,造成 ”奇奇怪怪“ 的问题。

嵌入式开发 中, 经历避免使用大的临时数组——他们使用的是堆栈。


---
》》很难解决了.
可以定义成非临时变量。
法1) 放在函数外。 就是全局的了。
char cmdline_buf[1500];
void ABC()
{
}
这样, 函数返回后,别的函数还可临时用一下这个数据。
法2) 前面加上static 放在函数内。 就是静态持久的了。
void ABC()
{
        static char cmdline_buf[1500];
}


不是临时变量,这样用的就不是堆栈,就没问题。
不是临时变量, 这段内存始终不会释放。是专用内存。

//反正,看样子, 这个数组不是偶尔才用,变成了事实上的专用内存


》》》》
不知还有没有其它的解决方法?我也尝试过用malloc来分配内存也是一样的效果,真的是很奇怪.
试试这样:
  1. static char cmdline_buf0[512+16+1500+512];
  2. char *cmdline_buf=&cmdline_buf0[512];
  3. cmdline_buf  +=  (~(int)cmdline_buf)&0x0F;
  4. cmdline_buf[0]  = 0;
复制代码

点评

使用char cmdline_buf[1500]是旧版本的(也就是速度比较快的) 新的版本是使用专用内存块的. 另外这一个内存必须是这个函数专用的,并且每次运行该函数使用内存都不应该一样.. 因为这个函数里面的命令会再次调用  详情 回复 发表于 2014-12-23 14:52
回复

使用道具 举报

发表于 2014-12-23 14:52:40 | 显示全部楼层
mdyblog 发表于 2014-12-23 13:31
char cmdline_buf[1500];
这样可能会引起堆栈溢出。
嵌入式开发,最容易出现 堆栈溢出——内存太少, ...


使用char cmdline_buf[1500]是旧版本的(也就是速度比较快的)

新的版本是使用专用内存块的.

另外这一个内存必须是这个函数专用的,并且每次运行该函数使用内存都不应该一样..
因为这个函数里面的命令会再次调用这个函数,如果内存块一样的话就会出问题的.

所以上面的方法是没用的.

点评

1) 嵌入式,尽量避免嵌套调用。 yinwi堆栈有限。 2)可以试试: #define NUM_CMDBUF 6 char id_cmdbuf=0; //有些命令需要重置为0,故为全局 int ABC() { static char cmdline_bufs[NUM_CMDBUF][5  详情 回复 发表于 2014-12-23 15:23
这样就有溢出的可能了。反复调用这个函数,会导致内存消耗变大,这样就容易间接造成内存冲突。  详情 回复 发表于 2014-12-23 15:07
>>因为这个函数里面的命令会再次调用这个函数, 你说,会嵌套调用自己?  详情 回复 发表于 2014-12-23 14:58
回复

使用道具 举报

发表于 2014-12-23 14:58:36 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-23 15:03 编辑
chenall 发表于 2014-12-23 14:52
使用char cmdline_buf[1500]是旧版本的(也就是速度比较快的)

新的版本是使用专用内存块的.


>>因为这个函数里面的命令会再次调用这个函数,
你是说,会嵌套调用自己?
回复

使用道具 举报

发表于 2014-12-23 15:07:39 | 显示全部楼层
chenall 发表于 2014-12-23 14:52
使用char cmdline_buf[1500]是旧版本的(也就是速度比较快的)

新的版本是使用专用内存块的.

这样就有溢出的可能了。反复调用这个函数,会导致内存消耗变大,这样就容易间接造成内存冲突。

点评

所有执行的命令都是通过这个函数来执行的. 一个比较常见的情况就是执行了一个批处理..这时批处理里面的命令还是需要使用这个函数.. 另外批处理里面还要再次调用批处理等.  详情 回复 发表于 2014-12-23 15:51
回复

使用道具 举报

发表于 2014-12-23 15:23:12 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-23 16:42 编辑

chenall 发表于 2014-12-23 14:52
使用char cmdline_buf[1500]是旧版本的(也就是速度比较快的)

新的版本是使用专用内存块的.


1) 嵌入式,尽量避免嵌套调用。 因为堆栈有限。

2)可以试试:
  1. #define  NUM_CMDBUF  6    //嵌套调用层级
  2. volatile char id_cmdbuf=0;  //有些命令需要重置为0,故为全局
  3. int ABC()
  4. {
  5.     static int cmdline_bufs[NUM_CMDBUF][(32+1500+32)/sizeof(int)];
  6.     char inclv=1;  //必须局部
  7.     char *cmdline_buf=((char*)&cmdline_bufs[id_cmdbuf][0])+32;
  8.     if(id_cmdbuf  >= NUM_CMDBUF )
  9.     {   //printf("命令层次太深,命令被忽略\n");
  10.         return -1;
  11.     }
  12.     id_cmdbuf+=inclv;
  13.     cmdline_buf[0]  = 0;

  14.     ///...努力干活中...


  15.     id_cmdbuf-=inclv;  if(id_cmdbuf<0) id_cmdbuf=0;
  16.     return 0;
  17. }
复制代码

注意, 碰到某些不返回的命令,如configfile;   id_cmdbuf 重置为0。如果因此碰到冲突,可把当前命令中的重要参数提出来,单独存放。
碰到有些命令,可以提前释放cmd_buf:
  1. id_cmdbuf-=inclv;  inclv=0;
复制代码

回复

使用道具 举报

发表于 2014-12-23 15:51:43 | 显示全部楼层
不点 发表于 2014-12-23 15:07
这样就有溢出的可能了。反复调用这个函数,会导致内存消耗变大,这样就容易间接造成内存冲突。

所有执行的命令都是通过这个函数来执行的.

一个比较常见的情况就是执行了一个批处理..这时批处理里面的命令还是需要使用这个函数..

另外批处理里面还要再次调用批处理等.

点评

麻烦, 试试上面的方法。 该方法限定 嵌套的层次。 说明一下即可。实际一般也就几曾。 如果可以, 先将最新的0.46a出个版本,大家先用着。 后面再考虑怎么处理(处理可能伤筋动骨,那就很费时了) 上面 定的  详情 回复 发表于 2014-12-23 16:35
回复

使用道具 举报

发表于 2014-12-23 16:35:32 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-23 16:49 编辑
chenall 发表于 2014-12-23 15:51
所有执行的命令都是通过这个函数来执行的.

一个比较常见的情况就是执行了一个批处理..这时批处理里面 ...

麻烦, 试试上面的 #601楼 方法。 该方法限定 嵌套的层次。每一层有自己专用的cmdbuf.
说明一下即可。实际一般也就几层。

如果可以, 先将最新的0.46a出个版本,大家先用着。(我等着用)
后面再考虑怎么处理(处理可能伤筋动骨,那就很费时了)
而且还要改的, 因为实际0227还是比20110714慢很多。
80G的分区 要 15秒, 还是太长。
估计不是一时半刻的事。

上面 定的是6层。
如果内存够, 可以调大点。



---另外是否考虑command 运行脚本时,是否给开关,也可给个命令。
或者id_cmdbuf放到固定的地址,write 可以修改为0.
使得可以初始化命令层级。(实际不返回了)
回复

使用道具 举报

发表于 2014-12-23 19:28:11 | 显示全部楼层
虽然表面上看起来是这里的问题,不过我估计应该有更深的原因.

我通过在MAP_FUNC函数里面插入一些DEBUG信息,发现是blocklist_func的问题.在map 里面调用blocklist_func命令时等待了很长的时间.

看来还得继续花时间继续跟踪一下blocklist的情况.

你可以测试一下以下命令使用的时间.
blocklist (hd0)xxxx+yyyy

@不点,对于(hdx)AAAA+BBb是不是可以不用执行blocklist_func?

另外请yaya确认下,0.4.6a对map函数的修改是否有问题.
0.4.5c的map命令调用blocklist_func时只调用了disk_read_blocklist_func一次,而0.4.6a则调用了很多次..

所以0.4.6a应该会比0.4.5c慢上很多.

点评

估计是 blocklist (hd0)xxxx+yyyy 的问题。 前面 测试中, 不用 blocklist (hd0)xxxx+yyyy 直接用 (hd0,1) 瞬间完成。  详情 回复 发表于 2014-12-23 19:38
回复

使用道具 举报

发表于 2014-12-23 19:38:47 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-23 19:40 编辑
chenall 发表于 2014-12-23 19:28
虽然表面上看起来是这里的问题,不过我估计应该有更深的原因.

我通过在MAP_FUNC函数里面插入一些DEBUG信 ...


估计是  blocklist (hd0)xxxx+yyyy 的问题。
前面 测试中,
不用 blocklist (hd0)xxxx+yyyy的形式。
直接用  (hd0,1) 瞬间完成——这才是我要的效果。
  1. map    --in-place     (hd0,1)    (hd1)
复制代码

#或 map    --in-place     (hd0,1)    (hd1,0)
回复

使用道具 举报

发表于 2014-12-23 19:47:12 | 显示全部楼层
对于(hdx)AAAA+BBb是不是可以不用执行blocklist_func?

即使执行了也不可能慢。对于任何文件,map 所调用的 blocklist 命令,都只打开它的第一扇区和末尾扇区,这基本不花费时间。

我觉得,如果有问题,那是好事,正好可以用它来暴露代码的错误。“问题” 就是下蛋的母鸡,如果把母鸡宰杀了,那就没有鸡蛋了。平时你想找这样的母鸡,那还找不着呢。所以,问题报告是非常珍贵的。

根据 mdyblog 的报告,早期的版本没有问题。那就可以证明,不是因为对 (hdx)AAAA+BB 调用了 blocklist_func 所引起的问题。因此也能断定,是后来的代码中的错误,蔓延到、影响到 blocklist 的错误了。比如,有可能是某个内存溢出造成的结果。严重的内存溢出会导致死机。死机问题其实还比较容易定位。但不严重的内存溢出,会产生更加难以追踪的错误。



回复

使用道具 举报

 楼主| 发表于 2014-12-23 20:32:20 | 显示全部楼层
另外请yaya确认下,0.4.6a对map函数的修改是否有问题.
0.4.5c的map命令调用blocklist_func时只调用了disk_read_blocklist_func一次,而0.4.6a则调用了很多次..

为了确定映像文件的连续性,0.4.6a 确实是对没有 --mem 参数的映像文件 1 扇区 1 扇区地从头读到尾。这样确实比 0.4.5c 慢得多。
但这不是问题的根本。从 mdyblog 报告的情况看,a 与 c 速度差不多,且出问题的时间段的 3 个补丁与 blocklist_func 无关。

点评

》》为了确定映像文件的连续性,0.4.6a 确实是对没有 --mem 参数的映像文件 1 扇区 1 扇区地从头读到尾。这样确实比 0.4.5c 慢得多。 但这不是问题的根本。从 mdyblog 报告的情况看,a 与 c 速度差不多,且出问题的  详情 回复 发表于 2014-12-23 22:33
回复

使用道具 举报

发表于 2014-12-23 21:40:17 | 显示全部楼层
经过追踪,目前发现长时间执行的代码段在disk_io.c里面如下代码(0.4.5c),相差了一倍的时间,很是怪异.


  1.           while (filepos > blk_buf.cur_filepos)
  2.             {
  3.               //if ((filepos - ((*((unsigned long*)FSYS_BUF)) & ~(buf_geom.sector_size - 1)))
  4.               //  >= buf_geom.sector_size)
  5.               if ( (filepos - (blk_buf.cur_filepos & (-(unsigned long long)buf_geom.sector_size)))
  6.                   >= buf_geom.sector_size )
  7.                 {
  8.                   //(*((unsigned long*)FSYS_BUF)) += buf_geom.sector_size;
  9.                   blk_buf.cur_filepos += buf_geom.sector_size;
  10.                   //(*((unsigned long*)(FSYS_BUF+8)))++;
  11.                   blk_buf.cur_blknum++;

  12.                   //if ((*((unsigned long*)(FSYS_BUF+8))) >= *((unsigned long*) ((*((unsigned long*)(FSYS_BUF+4))) + 4)) )
  13.                   if (blk_buf.cur_blknum >= blk_buf.cur_blklist->length )
  14.                     {
  15.                       //(*((unsigned long*)(FSYS_BUF+4))) += 8;        /* BLK_CUR_BLKLIST */
  16.                       blk_buf.cur_blklist++;
  17.                       //(*((unsigned long*)(FSYS_BUF+8))) = 0;        /* BLK_CUR_BLKNUM */
  18.                       blk_buf.cur_blknum = 0;
  19.                     }
  20.                 }
  21.               else
  22.                 //(*((unsigned long*)FSYS_BUF)) = filepos;
  23.                 blk_buf.cur_filepos = filepos;
  24.             }
复制代码

点评

我给出另外一种思路,供参考。 用汇编语言实现这段代码的功能,看看它还会出问题吗? gcc 是靠不住的。 我甚至怀疑它的开发团队,你懂的。  详情 回复 发表于 2014-12-24 09:59
下面是根据猜测的数据结果转换的O(0)复杂度的为代码。填上对应的实际类型。  详情 回复 发表于 2014-12-23 23:22
这个算法,对 小的扇区序列问题。 对到的扇区序列时间上来了。 因为改算法的时间复杂度为O(n) 是通过每次”尝试加1“实现。 改成 直接计算 出结果,直接一步加到位。 不用尝试了。 这样时间复杂度为O(0)  详情 回复 发表于 2014-12-23 22:53
回复

使用道具 举报

发表于 2014-12-23 22:33:42 | 显示全部楼层
2011yaya2007777 发表于 2014-12-23 20:32
为了确定映像文件的连续性,0.4.6a 确实是对没有 --mem 参数的映像文件 1 扇区 1 扇区地从头读到尾。这样 ...

》》为了确定映像文件的连续性,0.4.6a 确实是对没有 --mem 参数的映像文件 1 扇区 1 扇区地从头读到尾。这样确实比 0.4.5c 慢得多。
但这不是问题的根本。从 mdyblog 报告的情况看,a 与 c 速度差不多,且出问题的时间段的 3 个补丁与 blocklist_func 无关。
---------------

这么说, 现在问题查不多找全了。
1)
-        char cmdline_buf[1500];
+        char *cmdline_buf = cmd_buffer;
--------------
是20120324比20120227慢的原因。
,这个可 试试前面 #601楼 方法。 该方法限定 嵌套的层次。每一层有自己专用的cmdbuf.
说明一下即可。实际一般也就几层。

2)
0.4.6a 确实是对没有 --mem 参数的映像文件 1 扇区 1 扇区地从头读到尾。这样确实比 0.4.5c 慢得多。
---
是0.46a 后来版本 如此慢的原因。
对与扇区序列,可以去掉连续性检查。参数本身就能看出好似否连续。
(hd0)a+b
不会出现不连续。
(hd0)1+100,200+100
不用检查,就知道 不连续。

只有基于文件名的才需要检查。应该读一遍即可,以获得扇区序列。

--------------
3a)应该还差个原因, 使得 20120227 比 20110714慢很多。
一直80G的分区, 要 15秒。
估计:还是 连续性检查的原因。

3b)应该还差个原因,20110714  不是瞬间完成。

  1. map --in-place  (hd0,1) (hd1)
复制代码
是瞬间完成
耗时差不多和大小成正比。
估计:
即使很早的版本, 对扇区序列,和文件是统一处理,都至少有一次从头读到尾的检查。
所以 耗时差不多和大小成正比。

所以,扇区序列,应该和文件分开处理。
扇区序列 不需要 “实地"连续心检查。
这样耗时就和大小无关时间复杂度为O(0),而不是 O(n)
就是瞬间完成。

应该和文件分开考虑
处理的时候,2个还是可以合并处理,不会有代码冗余:
1) 对与文件map,选获得扇区序列, check_map_sect_lsit()
这样 就转变为扇区序列的map,执行2).
2) 执行扇区序列的map


执行扇区序列map  就是文件map的简化过程,少调用一个子过程,因而瞬间完成。


回复

使用道具 举报

发表于 2014-12-23 22:53:00 | 显示全部楼层
chenall 发表于 2014-12-23 21:40
经过追踪,目前发现长时间执行的代码段在disk_io.c里面如下代码(0.4.5c),相差了一倍的时间,很是怪异.

这个算法,对 小的扇区序列问题。
对到的扇区序列时间上来了。
因为改算法的时间复杂度为O(n)
是通过每次”尝试加1“实现。

改成 直接计算 出结果,直接一步加到位。
不用尝试了。
这样时间复杂度为O(0)

就是多费脑汁, 思考出个计算公示。

---
我不清楚用到的数据结构,
不然 , 可以帮忙给出计算公示。
回复

使用道具 举报

发表于 2014-12-23 23:22:47 | 显示全部楼层
chenall 发表于 2014-12-23 21:40
经过追踪,目前发现长时间执行的代码段在disk_io.c里面如下代码(0.4.5c),相差了一倍的时间,很是怪异.

下面是根据猜测的数据结果转换的O(0)复杂度的为代码。填上对应的实际类型。
  1. const sector_size=buf_geom.sector_size;
  2. const length=blk_buf.cur_blklist->length;
  3. const d1=blk_buf.cur_filepos & (-sector_size);
  4. const d2=filepos - d1;
  5. if ( blk_buf.cur_filepos < filepos )
  6. {
  7.         const n1 = d2/sector_size;
  8.         if(n1>0)
  9.         {
  10.                 blk_buf.cur_blknum+=n1;
  11.                 const n2 = cur_blknum / length;
  12.                 blk_buf.cur_blklist += n2;
  13.                 blk_buf.cur_blknum -= n2 * length;
  14.         }
  15.         blk_buf.cur_filepos = filepos;
  16. }
复制代码

点评

大部份参与计算的都是unsigned long long的. 64位的除法,编译不通过,需要自己写一个64位除法的函数. 目前看来应该和编译器优化有一些关系,同样的代码,执行结果也一样,但所花的时间差了一倍.  详情 回复 发表于 2014-12-24 09:17
回复

使用道具 举报

发表于 2014-12-24 09:17:58 | 显示全部楼层
mdyblog 发表于 2014-12-23 23:22
下面是根据猜测的数据结果转换的O(0)复杂度的为代码。填上对应的实际类型。

大部份参与计算的都是unsigned long long的.

64位的除法,编译不通过,需要自己写一个64位除法的函数.

目前看来应该和编译器优化有一些关系,同样的代码,执行结果也一样,但所花的时间差了一倍.

点评

buf_geom.sector_size; blk_buf.cur_blklist->length; 的数值 是个很小的数值,可以用一个unsigned short表示。这样一个简单的除法如下。  详情 回复 发表于 2014-12-24 09:38
回复

使用道具 举报

发表于 2014-12-24 09:38:04 | 显示全部楼层
本帖最后由 mdyblog 于 2014-12-24 09:48 编辑
chenall 发表于 2014-12-24 09:17
大部份参与计算的都是unsigned long long的.

64位的除法,编译不通过,需要自己写一个64位除法的函数.


buf_geom.sector_size;
blk_buf.cur_blklist->length;
的数值 是个很小的数值,可以用一个unsigned short表示。这样一个简单的除法如下。

  1. typedef unsigned long long u64;
  2. u64 div64mini(u64  a, unsigned short b)
  3. {   register unsigned long a1=(unsigned long)(a>>32);  unsigned long a2=(unsigned long )a;
  4.     unsigned long a1v=a1/ b; a1 -=  a1v*b;
  5.     a1  <<= 16;
  6.     unsigned long amv=a1/ b; a1 -=  amv*b;
  7.     a1  <<= 16;
  8.     unsigned long a2v=a2/ b; a2 -=  a1v*b;
  9.     a2 += a1;
  10.     unsigned long a3v=a2/ b;
  11.     return (((u64)a1v)<<32)  +  (((u64)amv)<<16)+ (a2v+a3v);
  12. }

  13. const unsigned short sector_size=(unsigned short)(buf_geom.sector_size);
  14. const unsigned short length=(unsigned short)(blk_buf.cur_blklist->length);
  15. const d1=blk_buf.cur_filepos & (-sector_size);
  16. const d2=filepos - d1;
  17. if ( blk_buf.cur_filepos < filepos )
  18. {   const n1 =div64mini(d2,sector_size);
  19.     if(n1>0)
  20.     {   blk_buf.cur_blknum+=n1;
  21.         const n2 = div64mini(cur_blknum, length);
  22.         blk_buf.cur_blklist += n2;
  23.         blk_buf.cur_blknum -= n2 * length;
  24.     }
  25.     blk_buf.cur_filepos = filepos;
  26. }
复制代码
回复

使用道具 举报

发表于 2014-12-24 09:59:31 | 显示全部楼层
chenall 发表于 2014-12-23 21:40
经过追踪,目前发现长时间执行的代码段在disk_io.c里面如下代码(0.4.5c),相差了一倍的时间,很是怪异.

我给出另外一种思路,供参考。

用汇编语言实现这段代码的功能,看看它还会出问题吗?

gcc 是靠不住的。

我甚至怀疑它的开发团队,你懂的。

回复

使用道具 举报

发表于 2014-12-24 10:59:22 | 显示全部楼层
修改了一下上面的代码(复杂度还是不变,只是尽量减少了一些循环内部的计算),目前时间应该和0227差不多.

要继续优化的话就只能考虑前面mdyblog给的方案了.

grub4dos-0.4.5c-2014-12-24.7z

259.02 KB, 下载次数: 3

点评

测试结果, 10秒。 和120322查不多(11秒)。 120227 是 3秒  详情 回复 发表于 2014-12-24 11:17
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1|闽公网安备35020302032614号 )

GMT+8, 2026-8-30 05:31

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表