在 SkyEye 中有趣的 BogoMIPS
改进 44b0 的实现后,发觉一件有趣的事情。本来 BogoMIPS 用于计算一秒钟内 CPU 运行了多少次循环。
按道理是越高值越好。
而在 SkyEye 中虚拟的硬件系统确非如此,
对比以下输出结果(在 SkyEye 中运行),
响应快的却是 BogoMIPS 较低的那一个。
探究原因:虚拟的 timer 发生中断的实际间隔与要求间隔差距越大,BogoMIPS越高。
######### uClinux-2.6.19-uc1 在 SkyEye 中输出 ##########
/> cat /proc/cpuinfo
Processor : Samsung-S3C44B0x rev 0 (v4l)
BogoMIPS : 1.44
Features : swp 26bit
CPU implementer : 0x44
CPU architecture: 4T
CPU variant : 0x30
CPU part : 0x770
CPU revision : 0
Hardware : S3C44B0X Development Board
Revision : 0000
Serial : 0000000000000000
######### Armlinux-2.6.14 在 SkyEye 中输出 ##########
/ $ cat /proc/cpuinfo
Processor : ARM920Tid(wb) rev 0 (v4l)
BogoMIPS : 12.80
Features : swp half thumb
CPU implementer : 0x41
CPU architecture: undefined/unknown
CPU variant : 0x0
CPU part : 0x920
CPU revision : 0
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown: format A
Cache format : Harvard
I size : 16384
I assoc : 64
I line length : 32
I sets : 8
D size : 16384
D assoc : 64
D line length : 32
D sets : 8
Hardware : SMDK2410
Revision : 0000
Serial : 0000000000000000 模拟的时间中断间隔产生密度与一般指令执行速度近似正态(考虑执行代码处理时间中断)。
尝试过后,大约速度如下(不更改 armio 的 TC_DIVIDER 前提下):
没有 DBCT 的 arm7tdmi 的实际速度约为 2MHz。
有 DBCT 的 arm7tdmi 的实际速度约为 5~6MHz。
当然这是运行在 1.2GHz 的 Windows XP 主机得出的粗略数据。
可见现在的 SkyEye 仍有相当大的空间作改进,
不过因为个人原因我暂时退出开发,期望有志人士与现有团队继续努力...
加油...
以下是没有DBCT的测试速度简单补丁。
这是我的输出结果:
1. 调用时间中断,每1毫秒一次
1) 没有DBCT
*************************************************
time in microseconds: 1250000
NumInstrs: 2457669
speed: 1.97 MHz
*************************************************
2) 有DBCT
*************************************************
time in microseconds: 6562500
NumInstrs: 19608837
speed: 2.99 MHz
*************************************************
2. 空循环
1) 没有 DBCT
*************************************************
time in microseconds: 4984375
NumInstrs: 12545425
speed: 2.52 MHz
*************************************************
2) 有 DBCT
*************************************************
time in microseconds: 4250000
NumInstrs: 95637808
speed: 22.50 MHz
*************************************************
Index: arch/arm/common/armio.c
===================================================================
--- arch/arm/common/armio.c
+++ arch/arm/common/armio.c
@@ -71,6 +71,7 @@
state->instr_count++;
#endif //DBCT_TEST_SPEED
//AJ2D--------------------------------------------------------------------------
+ if (!skyeye_config.no_dbct) state->NumInstrs++;
prescale--;
if (prescale < 0) {
prescale = DIVISOR;
Index: utils/main/skyeye.c
===================================================================
--- utils/main/skyeye.c
+++ utils/main/skyeye.c
@@ -482,6 +482,38 @@
exit( ret);
}
+#define TEST_ARM_SPEED
+#ifdef TEST_ARM_SPEED
+#include "portable/gettimeofday.h"
+static struct timeval speed_tv;
+static void init_test_speed()
+{
+ gettimeofday(&speed_tv, NULL);
+}
+
+static void test_speed()
+{
+ struct timeval tv;
+ uint64_t msec;
+ ARMul_State *state;
+
+ gettimeofday(&tv, NULL);
+
+ if (skyeye_config.mach == NULL || skyeye_config.arch == NULL ||
+ skyeye_config.arch->arch_name == NULL || strcmp(skyeye_config.arch->arch_name, "arm") != 0 ||
+ (state = (ARMul_State*)skyeye_config.mach->state) == NULL) return;
+
+ msec = (uint64_t)tv.tv_usec + (uint64_t)tv.tv_sec * 1000000ULL;
+ msec -= (uint64_t)speed_tv.tv_usec + (uint64_t)speed_tv.tv_sec * 1000000ULL;
+ printf("\n*************************************************\n");
+ printf("time in microseconds: %llu\n", msec);
+ printf("NumInstrs: %llu\n", state->NumInstrs);
+ printf("speed: %.2f MHz\n", (float)state->NumInstrs / (float)msec);
+ printf("*************************************************\n");
+}
+#endif
+
+
#ifdef __MINGW32__
static BOOL init_win32_socket()
{
@@ -670,6 +702,11 @@
fflush(stdout);
+#ifdef TEST_ARM_SPEED
+ init_test_speed();
+ signal(SIGINT, test_speed);
+#endif
+
if (debugmode == 0)
sim_resume (0);
else{
页:
[1]