作者littleshan (我要加入剑道社!)
看板C_and_CPP
标题Re: [问题] 为什麽作业系统都用C写? 而不用C++呢?
时间Sun Mar 8 12:33:10 2009
※ 引述《tinlans ( )》之铭言:
: 显然用 C++ 的 OO 机制是会比 C 的 OO 慢一点
: (
: 其实是因为我 C 的部分没有实作出 OO 特性,
: 它是 static 语意 (要拔掉 union 然後用 void * 代替资料栏位),
: 完全模拟 OO 的话那 0.2 秒的差异马上会不见,
: 有人想战的话我再做细部实作 XD
: )
先不讨论它的 static 语意,在我看来把 function pointer 直接放
在 struct 中有太占空间的缺点,每增加一项操作,物件所占的空间
也会一起增加。
因此我把它改成使用 vtable 的版本:
poly.c:
struct Vtable;
struct Data {
struct Vtable* vptr;
enum Type type;
union Mixed mixed_data;
};
struct Vtable {
void (*changeValue)(struct Data *);
int (*toInt)(struct Data *);
};
client.c:
int main(){
...
while(i--) (*data->vptr->changeValue)(data);
...
}
有趣的是,这样改过以後,C 的版本依然比 C++ 快了一点。为了了
解它快在哪里,我编出了 assembly 并检视核心的回圈部份:
C C++
.L2: │ .L4:
movq (%rbp), %rax │ movq (%rbp), %rax
addl $1, %ebx │ addl $1, %ebx
movq %rbp, %rdi │ movq %rbp, %rdi
call *(%rax) │ call *(%rax)
cmpl $500000000, %ebx │ .LEHB2:
jne .L2 │ cmpl $500000000, %ebx
│ jne .L4
两边根本是一样的:this 放在 rbp 中,并取出 function pointer
放在 rax 内。那麽关键的 function 内容呢?
double_change_value: │ _ZN6Double11changeValueEv:
.LFB37: │ .LFB41:
movsd .LC0(%rip), %xmm0 │ movsd .LC0(%rip), %xmm0
addsd 16(%rdi), %xmm0 │ addsd 8(%rdi), %xmm0
movsd %xmm0, 16(%rdi) │ movsd %xmm0, 8(%rdi)
ret │ ret
唯一的差别是 16(%rdi) 与 8(%rdi),因为 member 在物件中的位置
不一样。我有想过也许是 alignment 的问题,因此多塞了一个变数进
class 中,使得两边的 assembly 完全相同。但测出来的时间并没有
任何改变。
这麽一来我就很不解了,速度到底是差在哪?
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.121.120.91
1F:→ suhorng:这一串讨论越来越没意义了... 03/08 12:48
2F:推 wowtiger:要不要测一下 alignment 32 XD 或者 64 如果有支援的话 03/08 12:52
3F:→ wowtiger:同样 CODE 不同效能的问题 我是查到记忆体位置问题啦 03/08 12:53
4F:推 herman602:谁寄信给Bjarne Stroustrup请他开释一下 03/08 13:48
5F:→ tinlans:不过我想强调的重点是,几乎不会有人在 kernel 用 C 写出 03/08 13:50
6F:→ tinlans:这样的东西,反倒是第一种 c + switch case + union 的居 03/08 13:51
7F:→ tinlans:多,但是那种写法通常比 C++ 用 vtable 跳还慢 XD 03/08 13:51
8F:→ tinlans:你真的想量回圈速度的话可能要用 getrusage() 抓比较准, 03/08 13:55
9F:→ tinlans:因为 C++ 进入 main 前做的事情跟 C 不一样。 03/08 13:56
11F:推 yoco315:很有趣阿 03/08 14:28