{多线程, 性能} linux futex

319 views
Skip to first unread message

redsea

unread,
Sep 2, 2008, 10:31:44 PM9/2/08
to TopLanguage
mutex 是多线程编程中常用的原语, 因此值得进行优化.

futex 不是 mutex, 线程可以用futex来检测 userspace 的某个值, 值符合则睡眠等待唤醒的一个api, 通过这个
futex 可以在 userspace 实现 优化的 mutex; 优化的目的是, 在线程并发冲突不严重的情形下, mutex base
on futex 多数情况下不进行 kernel call, 只有真正需要睡眠, 或者需要唤醒睡眠进程的时候, 才需要进行 kernel
call, 大大降低了 kernel call 的次数.

这在一个线程 mutex 次数调用较多, 同时线程互相等待/唤醒 (并发冲突) 情形较少的时候, 对性能提高很有好处.

glibc 里面的 posix mutex (nptl) 就是用 futex 实现的.

如果临界区占用时间比例较高, 造成并发冲突概率很高的话, 这种 mutex 实现和每次都进行 kernel 调用的 mutex 相比优势就不

了---- 多数调用还是需要进入 kernel.

此时优化的重点又回到了多线程程序优化的基本点 --- 降低临界区占用时间比例, 提高并发程度. 例如, 保护整体数据结构的大锁改成多个保护部
分数据结构的小锁; 根据读写比因素改成读写锁等; 甚至改变数据结构实现, 用无锁编程等方法.

BTW:
windows 下面的 criticalSession 实现也有用 CAS 来避免 kernel 调用的优化. windows 下面的
mutex 实现我没有看过,

http://www.reddit.com/comments/6z4sv/
(reddit 也是 GFWed 的, proxy 或者梯子看)

Thin Lock vs. Futex

After my post on thin locks, several people asked me why not use a
futex (fast userspace mutex) instead. They referred to a Linux
implementation described in “Fuss, Futexes and Furwocks: Fast
Userlevel Locking in Linux” by Franke and Russel from IBM. The
questions prompted me to do some research, and here’s what I’ve found.
Futex is not mutex

Futex doesn’t have Lock/Unlock operations. Instead it’s a primitive
that may be used to implement a fast userspace mutex. The two relevant
operations are Wait and Wake. Both result in kernel calls, except in
one case: The Wait call takes two arguments: one is the address of a
user-defined integer variable, the other is the expected value of that
variable. If the values don’t match, the call returns immediately.
This prevents missed wakeup calls–a common problem with condition
variables.
Building a futex mutex

Buildning a mutex from those primitives is a nontrivial task. It
requires writing some user code to test and manipulate a user-level
integral variable representing the lock. A typical implementation (see
“Futexes are Tricky” by Ulrich Drepper–and also the code at the end of
this post) assigns tree states to a futex variable:

* zero means that the lock is not taken,
* one that it’s taken but no other thread is blocked on it,
* two means that the lock is taken and in all likelihood there are
threads waiting for it.

To lock the mutext, user code tries to CAS the futex variable from
zero to one. If successful, the call returns immediately (we have
taken the lock).

Unlock tests if the futex variable is equal to one (we are the owner,
and nobody is waiting). If true, it sets it to zero. This is the fast-
track common-case execution that doesn’t make any futex calls
whatsoever.

All other cases end up making futex kernel calls.
Let me summarize this

The fast path is implemented by the client. Only when the client
detects contention (the CAS failed), does she escalate to the kernel
call. However, before she can safely escalate, she has to wait for the
lock to be released, otherwise the thread that holds the lock might do
the wrong thing when unlocking. It’s up to the client to make the wait
busy (spinlock) or to use futex to conditionally sleep on the futex
variable.

Compare this with the thin lock implementation. Here too, the fast
path is implemented by the client. Only when the client detects
contention, does he inflate the lock (and escalate to the kernel
call). But before the lock can be inflated, he has to wait for the
lock to be released. In the current implementation this wait is busy.
What’s the main difference between the two?

The thin lock implementation inflates the lock only once–the first
time it detects contention. It then switches implementation to use OS
locking directly. The futex implementation escalates to the kernel
call every time there is contention.

The two algorithms are optimized for different scenarios. Thin lock
assumes that once contention happens, it will happen over and over
again. This assumption has some empirical support, as the authors of
the thin lock paper assert. Converseley, under heavy contention, the
futex implementation forces every thread to escalate, which involves
(potentially mutlitple) conditional waits.

Obviously there are many (often hidden) factors that might influence
performance under heavy contention, so I wouldn’t automatically assume
that the futex is slower. Only actual measurements could provide solid
arguments.

Ultimately, what weighs the heaviest against the use of a futexes in
monitors is how much that would special-case the Linux implementation.
Granted, Windows has its own “slim” locks, but they are different
enough from futexes to preclude significant refactoring. Plus they are
only available on Vista (Google for Slim Reader/Writer (SRW) Locks to
find out more).
Futex code

This is my version of the code described in Drepper’s article. CAS
stands for atomic compare-and-store. Here, CAS returns true on
success–
it has seen the expected value and it stored the new value in its
place.

class FastMutex
{
public:
FastMutex() : _word(0) {}
void lock()
{
// try to atimically swap 0 -> 1
if (CAS(&_word, 0, 1))
return; // success
// wasn't zero -- somebody held the lock
do
{
// assume lock is still taken, try to make it 2 and wait
if (_word == 2 || CAS(&_word, 1, 2))
{
// let's wait, but only if the value is still 2
futex_wait(&_word, 2);
}
// try (again) assuming the lock is free
} while (!CAS(&_word, 0, 2);
// we are here only if transition 0 -> 2 succeeded
}
void unlock()
{
// we own the lock, so it's either 1 or 2
if (atomic_decrement(&_word) != 1)
{
// it was 2
// important: we are still holding the lock!
_word = 0; // not any more
// wake up one thread (no fairness assumed)
futex_wake(&_word, 1);
}
}
private:
int _word;

};

Don’t design these mutexes at home!

The trickiest part of this algorithm is that a thread that doesn’t own
the lock may modify it. Look at the CAS from 1 to 2. This change may
become visible to the lock owner in the middle of unlock. Suppose that
the lock value was 2 to begin with. The unlocker decrements it to 1.
At this point another thread may CAS it back to 2 and call futex_wait.

* If the wait happens before the unlocker resets _word = 0, the
wakup call is already bound to happen.
* If, on the other hand, the unlocker manages to reset _word and
call futex_wake, we are still fine. The wakeup call won’t be lost,
because the other thread will enter futex_wait expecting 2 and finding
0 (or 1, if yet another thread grabbed the lock in the meanwhile).

And this is just one of the many possible interleavings! A full
analysis would require a separate post.

SevenCat

unread,
Sep 3, 2008, 1:25:31 AM9/3/08
to TopLanguage
win里的MUTEX基本上是CS,以前看过这个的代码,不过有点忘了似乎确实也是采用了类似的方法,futex好像是2.6才有的吧?
> This prevents missed wakeup calls-a common problem with condition
> variables.
> Building a futex mutex
>
> Buildning a mutex from those primitives is a nontrivial task. It
> requires writing some user code to test and manipulate a user-level
> integral variable representing the lock. A typical implementation (see
> "Futexes are Tricky" by Ulrich Drepper-and also the code at the end of
> The thin lock implementation inflates the lock only once-the first
> time it detects contention. It then switches implementation to use OS
> locking directly. The futex implementation escalates to the kernel
> call every time there is contention.
>
> The two algorithms are optimized for different scenarios. Thin lock
> assumes that once contention happens, it will happen over and over
> again. This assumption has some empirical support, as the authors of
> the thin lock paper assert. Converseley, under heavy contention, the
> futex implementation forces every thread to escalate, which involves
> (potentially mutlitple) conditional waits.
>
> Obviously there are many (often hidden) factors that might influence
> performance under heavy contention, so I wouldn't automatically assume
> that the futex is slower. Only actual measurements could provide solid
> arguments.
>
> Ultimately, what weighs the heaviest against the use of a futexes in
> monitors is how much that would special-case the Linux implementation.
> Granted, Windows has its own "slim" locks, but they are different
> enough from futexes to preclude significant refactoring. Plus they are
> only available on Vista (Google for Slim Reader/Writer (SRW) Locks to
> find out more).
> Futex code
>
> This is my version of the code described in Drepper's article. CAS
> stands for atomic compare-and-store. Here, CAS returns true on
> success-

up duan

unread,
Sep 3, 2008, 1:44:47 AM9/3/08
to pon...@googlegroups.com
是的,不过我一直在想,为什么user space的东西要比kernel space的东西快?当然是因为要辗转与两个地址空间……。
我的意思是我们有没有必要不区分多个地址空间?如同Singularity一样多好。即维持了进程的保护性【通过契约化的通信】,有实现了线程的高效。

2008/9/3 SevenCat <BastE...@gmail.com>

SevenCat

unread,
Sep 3, 2008, 1:48:17 AM9/3/08
to TopLanguage
不光是地址空间,涉及到一系列状态的保存和转换,要单是地址空间就很简单了.

On 9月3日, 下午1时44分, "up duan" <fixo...@gmail.com> wrote:
> 是的,不过我一直在想,为什么user space的东西要比kernel space的东西快?当然是因为要辗转与两个地址空间......。
> 我的意思是我们有没有必要不区分多个地址空间?如同Singularity一样多好。即维持了进程的保护性【通过契约化的通信】,有实现了线程的高效。
>
> 2008/9/3 SevenCat <BastEt.W...@gmail.com>

EC

unread,
Sep 3, 2008, 1:50:16 AM9/3/08
to TopLanguage
up duan:为什么user space的东西要比kernel space的东西快?
kernel安全大于效率?

SevenCat

unread,
Sep 3, 2008, 1:52:51 AM9/3/08
to TopLanguage
而且不是user space的东东比user space高.

On 9月3日, 下午1时44分, "up duan" <fixo...@gmail.com> wrote:
> 是的,不过我一直在想,为什么user space的东西要比kernel space的东西快?当然是因为要辗转与两个地址空间......。
> 我的意思是我们有没有必要不区分多个地址空间?如同Singularity一样多好。即维持了进程的保护性【通过契约化的通信】,有实现了线程的高效。
>
> 2008/9/3 SevenCat <BastEt.W...@gmail.com>

Linker

unread,
Sep 3, 2008, 1:56:43 AM9/3/08
to pon...@googlegroups.com


2008/9/3 EC <NetCl...@gmail.com>

up duan:为什么user space的东西要比kernel space的东西快?
kernel安全大于效率?
主要是用户态和内核态切换费时.






--
Linker M Lin
linker...@gmail.com

up duan

unread,
Sep 3, 2008, 1:57:17 AM9/3/08
to pon...@googlegroups.com
Activation Scheduler里面的说法是Kernel级别需要考虑各种通用情形,并且Kernel没有User级别对于该App所关心的领域具有的特定知识。
比如User Level的调度是在需要的时候进行,而Kernel Level的调度是在Timer Event到达的时候进行,所以Kernel的慢。而且这个慢不可逾越。

状态的保存在哪个级别都有啊,这应该不是原因

2008/9/3 SevenCat <BastE...@gmail.com>

up duan

unread,
Sep 3, 2008, 1:58:38 AM9/3/08
to pon...@googlegroups.com
>主要是用户态和内核态切换费时. 
是啊,所以说还是地址空间不同导致的呀。

2008/9/3 up duan <fix...@gmail.com>

莫华枫

unread,
Sep 3, 2008, 2:01:27 AM9/3/08
to pon...@googlegroups.com
通常kernel space的保护级别是0,user space则用低级别,通常为3(intel)。在ring0里的保护性检测多得多,引发的异常中断也多得多,性能也就差很多。

2008/9/3 EC <NetCl...@gmail.com>

up duan:为什么user space的东西要比kernel space的东西快?
kernel安全大于效率?


up duan

unread,
Sep 3, 2008, 2:09:30 AM9/3/08
to pon...@googlegroups.com
是这样吗?我怎么从来没有看到Intel的技术文档上说过mov指令在不同的ring上运行时性能有差异呢?
也没有见过说某个Interrupt只在ring0时出现。不过你说的倒确实有可能。虽然我认为可能性不大

2008/9/3 莫华枫 <longsh...@gmail.com>

SevenCat

unread,
Sep 3, 2008, 2:13:00 AM9/3/08
to TopLanguage
难道是我记错了,最底层的执行的级别上连内存异常都没有.

On 9月3日, 下午2时01分, "莫华枫" <longshank...@gmail.com> wrote:
> 通常kernel space的保护级别是0,user
> space则用低级别,通常为3(intel)。在ring0里的保护性检测多得多,引发的异常中断也多得多,性能也就差很多。
>
> 2008/9/3 EC <NetClos...@gmail.com>
>
> > up duan:为什么user space的东西要比kernel space的东西快?
> > kernel安全大于效率?
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/

莫华枫

unread,
Sep 3, 2008, 2:21:41 AM9/3/08
to pon...@googlegroups.com
mov是不会有差异的。但是那些与保护段有关的指令在ring0里会引发异常中断。
异常中断,记得好像是int0。最典型的就是缺页。经常看到的异常访问,就是来源于异常中断

2008/9/3 up duan <fix...@gmail.com>

SevenCat

unread,
Sep 3, 2008, 2:44:33 AM9/3/08
to TopLanguage
那些指令一般程序也用不到.

On 9月3日, 下午2时21分, "莫华枫" <longshank...@gmail.com> wrote:
> mov是不会有差异的。但是那些与保护段有关的指令在ring0里会引发异常中断。
> 异常中断,记得好像是int0。最典型的就是缺页。经常看到的异常访问,就是来源于异常中断
>
> 2008/9/3 up duan <fixo...@gmail.com>
>
>
>
> > 是这样吗?我怎么从来没有看到Intel的技术文档上说过mov指令在不同的ring上运行时性能有差异呢?
> > 也没有见过说某个Interrupt只在ring0时出现。不过你说的倒确实有可能。虽然我认为可能性不大
>
> > 2008/9/3 莫华枫 <longshank...@gmail.com>
>
> >> 通常kernel space的保护级别是0,user
> >> space则用低级别,通常为3(intel)。在ring0里的保护性检测多得多,引发的异常中断也多得多,性能也就差很多。
>
> >> 2008/9/3 EC <NetClos...@gmail.com>
>
> >>> up duan:为什么user space的东西要比kernel space的东西快?
> >>> kernel安全大于效率?
>
> >> --
> >> 反者道之动,弱者道之用
> >> m...@seaskysh.com
> >> longshank...@gmail.com
> >>http://blog.csdn.net/longshanks/
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/

redsea

unread,
Sep 3, 2008, 2:50:18 AM9/3/08
to TopLanguage
内核态程序不存在性能比用户态差的问题.

执行普通的指令(mov, 不缺页), ring0 的性能和 ring3 没有区别.

在某些特殊的 context, 例如硬中断, 访问缺页的地址, 系统应该是立刻 panic.

process context (就是 process 调用系统调用进行内核态, 例如调用 C 程序调用fread, 然后调用 read 进入
内核), 碰到缺页, 和userspace 一样, 引发换页.

说系统调用性能差主要的原因是系统调用这个 API 性能差:
1. 要切换部分 CPU 页表, 以便可以访问内核空间
我不知道这里 cache 是否起作用, 如果 cache 不起作用, 纯粹从内存读, 性能影响很大
2. 调用系统调用, 不像普通函数调用, 将参数压栈, 然后 call 就可以了, 而是要准备系统调用的描述结构, 指明要调用那个调用, 然后
将参数复制到一个内核可以访问的空间, 然后执行一个 trap.
这里面有内存复制, 性能也差.
对于 read 这样的调用, 返回值在 buffer 中, 倒一般不必再进行内容复制, 而是调用的时候, 对 buffer 进行
memory manger 部分的调用, 获取一个内核态可以访问这个地址的指针, 让内核程序可以直接将结果写到最终的内容中去.

总结, 做一个系统调用, 比一个函数调用要做的事情多很多, 所以性能差.

redsea

unread,
Sep 3, 2008, 2:53:06 AM9/3/08
to TopLanguage
64bit 的系统这个想法还有一定的可行性.
32bit 系统, 3G 内存一个进程我还觉得不够用, 如果内核和所有进程共享4g, 惨点.


On Sep 3, 1:44 pm, "up duan" <fixo...@gmail.com> wrote:
> 是的,不过我一直在想,为什么user space的东西要比kernel space的东西快?当然是因为要辗转与两个地址空间......。

莫华枫

unread,
Sep 3, 2008, 3:00:22 AM9/3/08
to pon...@googlegroups.com
不是说指令性能差,而是在保护级别的作用下,很多指令是无法在ring0下直接运行的,比如cli会引发异常中断

2008/9/3 redsea <red...@gmail.com>

redsea

unread,
Sep 3, 2008, 3:06:23 AM9/3/08
to TopLanguage
你好像掉反了, ring0 是内核级, ring3 是用户级.
你搞反了, 使得我理解成, 你认为内核级代码性能差.

redsea

unread,
Sep 3, 2008, 3:11:45 AM9/3/08
to TopLanguage
>为什么user space的东西要比kernel space的东西快
没有这一说, kernel space 的程序倒有办法写得比 userspace 更快, 例如调用 spinlock, mutex 等, 都不
必进行级别切换了.

我们有一些应用程序就是在 kernel space 里面写的, 为的就是更好的性能, 免得每秒钟收发24万个包, 每个包就要进行 ring 切
换.

On Sep 3, 1:44 pm, "up duan" <fixo...@gmail.com> wrote:
> 是的,不过我一直在想,为什么user space的东西要比kernel space的东西快?当然是因为要辗转与两个地址空间......。

up duan

unread,
Sep 3, 2008, 3:18:10 AM9/3/08
to pon...@googlegroups.com
逻辑上似乎一样快,但是你说Kernel快,我说user快,显然能看出来是有差异的。

不知道你对ULT(User Level Thread)关注过没有,它们的性能一般比KLT快的多,当然,原因我前面也说了。

futex不就是用户级别的快速的互斥量吗?

2008/9/3 redsea <red...@gmail.com>

SevenCat

unread,
Sep 3, 2008, 3:19:21 AM9/3/08
to TopLanguage
ULT和KLT这个是两码事,不能混为一谈.

redsea

unread,
Sep 3, 2008, 3:57:35 AM9/3/08
to TopLanguage
> 逻辑上似乎一样快,但是你说Kernel快,我说user快,显然能看出来是有差异的。
> 不知道你对ULT(User Level Thread)关注过没有,它们的性能一般比KLT快的多,当然,原因我前面也说了。
这个说法当然指的程序主体在 user space 里面跑.

我的说法是程序主体在 kernel 跑, 只有配置等程序跑在 user space.

只要切换少, user space 和 kernel space 的程序都可以提高性能.

这并不代表优化的 user space 程序可以跑过 优化的 kernel space 程序.

>
> futex不就是用户级别的快速的互斥量吗?

up duan

unread,
Sep 3, 2008, 4:26:27 AM9/3/08
to pon...@googlegroups.com
>Activation Scheduler里面的说法是Kernel级别需要考虑各种通用情形,并且Kernel没有User级别对于该App所关心的领域具有的特定知识。
>比如User Level的调度是在需要的时候进行,而Kernel Level的调度是在Timer Event到达的时候进行,所以Kernel的慢。而且这个慢不可逾越。

2008/9/3 redsea <red...@gmail.com>

redsea

unread,
Sep 3, 2008, 4:55:23 AM9/3/08
to TopLanguage
kernel level 为什么要等 timer event 切换 ? kernel thread 一样可以主动切换.

你想说的是, 懂得领域知识的 Scheduler 比通用的 schedule 好吧 ?

你转移论题了.

你在 kernel space 写程序, 也可以自己 schedule 啊.

up duan

unread,
Sep 3, 2008, 5:03:49 AM9/3/08
to pon...@googlegroups.com
就我所知,主动切换的在Windows下面不叫线程,叫纤程。Linux下没有什么办法能够控制Thread的切换,你只能在时间片内部自己出让,但是不能保证一定会给自己所拥有的另一个线程。

2008/9/3 redsea <red...@gmail.com>

redsea

unread,
Sep 3, 2008, 5:12:18 AM9/3/08
to TopLanguage
kernel api:

linux/sched.h

schedule() 就是出让处理器.

redsea

unread,
Sep 3, 2008, 5:14:59 AM9/3/08
to TopLanguage
当然这个也不保证切到哪个进程的 thread.

我们在 kernel 写程序也不用 thread, 用 tasklet, work queue.

好了, 不说了.

SevenCat

unread,
Sep 3, 2008, 5:17:27 AM9/3/08
to TopLanguage
我也不想说了,感觉难理解,难沟通.

莫华枫

unread,
Sep 3, 2008, 7:55:45 AM9/3/08
to pon...@googlegroups.com
回家翻了一下书,故事是这样的。
保护级别0最高,3最低。操作系统核心工作在0上,用户程序工作在3上。如果用户程序想要得到系统服务,必须call ring0上的代码。但是保护系统规定,低级别的代码不能直接call高级别的代码,也不能访问高级别的数据。否则,用户程序便可以随便访问核心的代码和数据了。为了完成ring3到ring0的call,cpu提供了"门"的机制。切换门以及相关的环境状态(一堆寄存器)需要开销。gdi属于访问频繁的服务,对程序性能影响很大。放在ring0里,每次调用都需要切换cpu保护状态,开销甚大。nt3.5是ms第一种真正完全利用了intel保护模式的操作系统。结果发现图形性能很差。应用程序只能在ring3中执行,无法搬进ring0,那么只能将图形处理部分分离出来,放进ring3。进而在nt4.0之后,将gdi移到ring3,以提高性能。代价就是可靠性变差。

呵呵,还是redsea说的对。:)
关于指令,我记反了,很多指令在ring3下会引发0D中断。比如cli,int等等。

另外,我也问个问题:在win32下,通常应用程序的非法操作不会引发整个操作系统的崩溃。但如果在kernal mode中的驱动程序存在非法操作,基本上就出蓝屏了。但我听说在unix中,一般设备驱动出现问题,也不会引发整个操作系统的崩溃。不知是真是假?
如果是真的,unix采用了什么样的方法做到的呢?


2008/9/3 莫华枫 <longsh...@gmail.com>

SevenCat

unread,
Sep 3, 2008, 8:08:49 AM9/3/08
to TopLanguage
我还以为我记错了呢。
linux下的这个设备驱动出错不崩溃的资料在哪里?直觉是不太可能的。

On Sep 3, 7:55 pm, "莫华枫" <longshank...@gmail.com> wrote:
> 回家翻了一下书,故事是这样的。
> 保护级别0最高,3最低。操作系统核心工作在0上,用户程序工作在3上。如果用户程序想要得到系统服务,必须call
> ring0上的代码。但是保护系统规定,低级别的代码不能直接call高级别的代码,也不能访问高级别的数据。否则,用户程序便可以随便访问核心的代码和数据了。为了完成ring3到ring0的call,cpu提供了"门"的机制。切换门以及相关的环境状态(一堆寄存器)需要开销。gdi属于访问频繁的服务,对程序性能影响很大。放在ring0里,每次调用都需要切换cpu保护状态,开销甚大。nt3.5是ms第一种真正完全利用了intel保护模式的操作系统。结果发现图形性能很差。应用程序只能在ring3中执行,无法搬进ring0,那么只能将图形处理部分分离出来,放进ring3。进而在nt4.0之后,将gdi移到ring3,以提高性能。代价就是可靠性变差。
>
> 呵呵,还是redsea说的对。:)
> 关于指令,我记反了,很多指令在ring3下会引发0D中断。比如cli,int等等。
>
> 另外,我也问个问题:在win32下,通常应用程序的非法操作不会引发整个操作系统的崩溃。但如果在kernal
> mode中的驱动程序存在非法操作,基本上就出蓝屏了。但我听说在unix中,一般设备驱动出现问题,也不会引发整个操作系统的崩溃。不知是真是假?
> 如果是真的,unix采用了什么样的方法做到的呢?
>
> 2008/9/3 莫华枫 <longshank...@gmail.com>
>
>
>
> > 不是说指令性能差,而是在保护级别的作用下,很多指令是无法在ring0下直接运行的,比如cli会引发异常中断
>
> > 2008/9/3 redsea <red...@gmail.com>
>
> > 内核态程序不存在性能比用户态差的问题.
>
> >> 执行普通的指令(mov, 不缺页), ring0 的性能和 ring3 没有区别.
>
> >> 在某些特殊的 context, 例如硬中断, 访问缺页的地址, 系统应该是立刻 panic.
>
> >> process context (就是 process 调用系统调用进行内核态, 例如调用 C 程序调用fread, 然后调用 read 进入
> >> 内核), 碰到缺页, 和userspace 一样, 引发换页.
>
> >> 说系统调用性能差主要的原因是系统调用这个 API 性能差:
> >> 1. 要切换部分 CPU 页表, 以便可以访问内核空间
> >> 我不知道这里 cache 是否起作用, 如果 cache 不起作用, 纯粹从内存读, 性能影响很大
> >> 2. 调用系统调用, 不像普通函数调用, 将参数压栈, 然后 call 就可以了, 而是要准备系统调用的描述结构, 指明要调用那个调用, 然后
> >> 将参数复制到一个内核可以访问的空间, 然后执行一个 trap.
> >> 这里面有内存复制, 性能也差.
> >> 对于 read 这样的调用, 返回值在 buffer 中, 倒一般不必再进行内容复制, 而是调用的时候, 对 buffer 进行
> >> memory manger 部分的调用, 获取一个内核态可以访问这个地址的指针, 让内核程序可以直接将结果写到最终的内容中去.
>
> >> 总结, 做一个系统调用, 比一个函数调用要做的事情多很多, 所以性能差.
>
> >> On Sep 3, 2:01 pm, "莫华枫" <longshank...@gmail.com> wrote:
> >> > 通常kernel space的保护级别是0,user
> >> > space则用低级别,通常为3(intel)。在ring0里的保护性检测多得多,引发的异常中断也多得多,性能也就差很多。
>
> > --
> > 反者道之动,弱者道之用
> > m...@seaskysh.com
> > longshank...@gmail.com
> >http://blog.csdn.net/longshanks/
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/

redsea

unread,
Sep 3, 2008, 9:33:06 AM9/3/08
to TopLanguage
> ring0上的代码。但是保护系统规定,低级别的代码不能直接call高级别的代码,也不能访问高级别的数据。否则,用户程序便可以随便访问核心的代码和数据了。为了完成ring3到ring0的call,cpu提供了"门"的机制。切换门以及相关的环境状态(一堆寄存器)需要开销。gdi属于访问频繁的服务,对程序性能影响很大。放在ring0里,每次调用都需要切换cpu保护状态,开销甚大。nt3.5是ms第一种真正完全利用了intel保护模式的操作系统。结果发现图形性能很差。应用程序只能在ring3中执行,无法搬进ring0,那么只能将图形处理部分分离出来,放进ring3。进而在nt4.0之后,将gdi移到ring3,以提高性能。代价就是可靠性变差。


不考虑安全性问题, 而是考虑程序兼容性问题, NT3.51 其实是很不错的, 很多 dos 程序, 什么直接操作 VGA 寄存器的,
dos 下直接操作串口 port 的, 都能够在 NT3.51 下面正确稳定运行. NT4.0 我记得兼容性差一些, 一部分不能正确运行了,
但系统还算稳定, 到 XP的时候, 某些 DOS 程序可以将系统弄死, 有时候是弄到鼠标键盘都不响应, 但是网络还能提供一些服务, 估计就是
驱动, GDI 的性能优化的和 WOW 之间不兼容造成的.

MS 自己说起过, windows 很多时候蓝屏死机是因为驱动的问题, 所以它后来要搞一个驱动认证. 认证要花不少钱, 但是, 效果, 我看
一般. 我有一个 usb 网卡, 在 linux 下非常稳定, 在 windows 下面, 无论是 ms 认证的驱动, 还是 ms 做的驱
动, 要么是工作一段时间之后停止响应, 要么干脆让系统死机.

> 呵呵,还是redsea说的对。:)
> 关于指令,我记反了,很多指令在ring3下会引发0D中断。比如cli,int等等。
>
> 另外,我也问个问题:在win32下,通常应用程序的非法操作不会引发整个操作系统的崩溃。但如果在kernal mode中的驱动程序存在非法操作,基本上就出蓝屏了。但我听说在unix中,一般设备驱动出现问题,也不会引发整个操作系统的崩溃。不知是真是假?
> 如果是真的,unix采用了什么样的方法做到的呢?


我只看过 linux 的kernel source, 设备驱动程序出问题, 还是要看什么问题吧, 也没有多神奇的, 有不少内核提供的服务函
数, 对参数还是有检查的, 如果是调用这个函数出错, 这个函数觉得这个错误大概不影响系统继续运行下去, 就不会 panic, 而是报告
bug 或者是 oops.

有些对性能要求不是那么高的驱动, 例如输入设备, usb 设备之类的, 可以写 user space 的驱动, 这个就容易解决了.

NjuBee

unread,
Sep 3, 2008, 10:48:48 AM9/3/08
to pon...@googlegroups.com
user space的东西真的比kernel space的东西快

不是说指令快, 而是库的支持等等.
内核的内存管理是整个system的, 不能想用户空间那样随便申请,申请速度也比用户空间慢, 栈也不能随便要多大就多大
内核的内存很关键, 不能随便放一个c库或其他库
可能不能使用浮点计算器.

等等等很多.
内核本来就是为用户空间提供虚拟的cpu和虚拟"无限"的内存, 如果内核要跑应用, 谁为内核虚拟.
还有安全问题.

很关键的应用可以跑在内核上: 网络, 文件系统, 等等, 这两个"真"的是是内核的一部.
像windows 的GDI, 和linux 曾经加进内核的web程序(好像的, 谁修正我?)

所以内核比用户空间慢.

2008/9/3 EC <NetCl...@gmail.com>:

莫华枫

unread,
Sep 3, 2008, 7:29:52 PM9/3/08
to pon...@googlegroups.com
没错,是搞反掉了。不好意思。时间长了记忆力衰退。老啦。:P

前面说的nt3.51,兼容性倒是没怎么试过。dos进程应该都在v86模式下(95则整个地,包括内核都在v86下),不知道ms在不同的操作系统里是怎么处理的。那时候ms的兼容性处理地还不错。现在就不谈了。

另外,windows只用了4个ring中的两个,0和3。那么unix系的呢?
会不会把设备驱动放在ring1或2里?就不会因为设备驱动的问题影响内核?

2008/9/3 redsea <red...@gmail.com>

redsea

unread,
Sep 3, 2008, 7:48:29 PM9/3/08
to TopLanguage
Linux 也只用了两个ring, 否则设备驱动读写一个端口, 读写一次设备内存都要模式切换一下, 代价太高了.

Hongzhang Liu

unread,
Sep 3, 2008, 9:16:17 PM9/3/08
to pon...@googlegroups.com
纤程 fiber 不过是用户级线程而已,在linux下照样可以实现出来。windows中也不存在保证切换到某个特定线程的方法;undocumented NT中提到nt为了GDI实现的高效,使用了两个未公开的API来实现一对线程之间的切换,不过并没有开放给应用程序使用。

2008/9/3 up duan <fix...@gmail.com>

up duan

unread,
Sep 3, 2008, 10:47:04 PM9/3/08
to pon...@googlegroups.com
整个都不知道跑题到哪儿了。

首先我能确定,Windows现在的GDI是在KernelSpace里面的。

对于Linux下实现Fiber,你给出个提示吧。Fiber的切换就完全是程序控制的,而不是Kernel控制的,这还不是让你自己控制切换?

现在大多数系统都只是用了Ring0和Ring3,对于现在的VMWare,Xen等虚拟机,Intel和AMD不约而同的增强了Ring1下的指令以便于支持高性能的多系统切换。

2008/9/4 Hongzhang Liu <hongzh...@gmail.com>

wing fire

unread,
Sep 3, 2008, 11:33:28 PM9/3/08
to pon...@googlegroups.com


2008/9/3 莫华枫 <longsh...@gmail.com>

回家翻了一下书,故事是这样的。
保护级别0最高,3最低。操作系统核心工作在0上,用户程序工作在3上。如果用户程序想要得到系统服务,必须call ring0上的代码。但是保护系统规定,低级别的代码不能直接call高级别的代码,也不能访问高级别的数据。否则,用户程序便可以随便访问核心的代码和数据了。为了完成ring3到ring0的call,cpu提供了"门"的机制。切换门以及相关的环境状态(一堆寄存器)需要开销。gdi属于访问频繁的服务,对程序性能影响很大。放在ring0里,每次调用都需要切换cpu保护状态,开销甚大。nt3.5是ms第一种真正完全利用了intel保护模式的操作系统。结果发现图形性能很差。应用程序只能在ring3中执行,无法搬进ring0,那么只能将图形处理部分分离出来,放进ring3。进而在nt4.0之后,将gdi移到ring3,以提高性能。代价就是可靠性变差。

我怎么记得当初慢是因为微内核的架构呢?GDI最终需要访问硬件,而用户代码是决不能访问硬件的。这是HAL导致的必然结果。微内核的情况下,GDI的最初由特定的service来完成,core负责维持通信,这个开销太大,于是,取消service,直接到到核心。这是我所听到的历史。
陷入到ring0虽然慢了点,但是比起微内核的通信还是快多了啊。后来的directX,才是真正的从用户空间直接访问硬件的,因为数据量太大,都通过ring0的话都慢的不行。也因为directX直接访问硬件的这个特性,所以,只要上了directX,好像C2,还是B2什么的安全级就不可能达到了。
另外,好像从XP还是2003开始,Audio这样的服务出现在了系统服务中,大概是因为现在机器性能够强,Audio这样开销不太大的功能重新回到微内核的service中去了吧。

 

wing fire

unread,
Sep 3, 2008, 11:36:56 PM9/3/08
to pon...@googlegroups.com


2008/9/3 莫华枫 <longsh...@gmail.com>

回家翻了一下书,故事是这样的。
保护级别0最高,3最低。操作系统核心工作在0上,用户程序工作在3上。如果用户程序想要得到系统服务,必须call ring0上的代码。但是保护系统规定,低级别的代码不能直接call高级别的代码,也不能访问高级别的数据。否则,用户程序便可以随便访问核心的代码和数据了。为了完成ring3到ring0的call,cpu提供了"门"的机制。切换门以及相关的环境状态(一堆寄存器)需要开销。gdi属于访问频繁的服务,对程序性能影响很大。放在ring0里,每次调用都需要切换cpu保护状态,开销甚大。nt3.5是ms第一种真正完全利用了intel保护模式的操作系统。结果发现图形性能很差。应用程序只能在ring3中执行,无法搬进ring0,那么只能将图形处理部分分离出来,放进ring3。进而在nt4.0之后,将gdi移到ring3,以提高性能。代价就是可靠性变差。

呵呵,还是redsea说的对。:)
关于指令,我记反了,很多指令在ring3下会引发0D中断。比如cli,int等等。

另外,我也问个问题:在win32下,通常应用程序的非法操作不会引发整个操作系统的崩溃。但如果在kernal mode中的驱动程序存在非法操作,基本上就出蓝屏了。但我听说在unix中,一般设备驱动出现问题,也不会引发整个操作系统的崩溃。不知是真是假?
如果是真的,unix采用了什么样的方法做到的呢?

这个好像没这么强,估计要看什么设备了。以前整过串口卡,很老的scci卡,照样死。还有热拔插硬盘,你拔光了试试,立马panic。
 

Feng Yu

unread,
Sep 3, 2008, 11:39:16 PM9/3/08
to pon...@googlegroups.com
linux下简单的gettimeofday系统调用要16us左右,其实内核里面就是执行一条语句 return jiffy;
也就是说ring3->ring0->ring3这个状态切换 需要16us左右时间。 16us在user space可以做非常多的工作了
可以执行大概5w个指令,所以要避免昂贵的系统调用。

2008/9/4 wing fire <wing...@gmail.com>:

--
专注 高性能 容错 分布服务器的实现(erlang)
http://mryufeng.javaeye.com

up duan

unread,
Sep 3, 2008, 11:43:01 PM9/3/08
to pon...@googlegroups.com
UNIX下的驱动模型从理论角度来说还比不上Windows的驱动模型呢。
UNIX稳定的基本原因是提供的API简单且相对一致,Programmer比较容易搞定怎么做才是对的。而且UNIX出现的时间长,很多问题大家都耳熟能详以至于能够避免了。
我的核心观点还是多进程比多线程安全,除非线程附加上了TLS,那又跟多进程差不多了。
实际上,现在的并行研究中,基于消息传递【类似于进程的地址空间隔离+IPC】的方式总是比基于共享内存【类似于多线程】的方式在理论上讨人喜欢。

2008/9/4 wing fire <wing...@gmail.com>

up duan

unread,
Sep 3, 2008, 11:46:05 PM9/3/08
to pon...@googlegroups.com
我前面的帖子提到了可以参照Singularity系统,不区分内核和用户这两个地址空间,会让性能提高不少。
至于由于少了隔离而导致的安全性下降,可以采用契约化的消息传递来提高,实际上Singularity的可靠性似乎很高。

2008/9/4 up duan <fix...@gmail.com>

Meng Xiangliang

unread,
Sep 4, 2008, 12:38:12 AM9/4/08
to pon...@googlegroups.com
请问16us这个时间是怎么得到的?在网上没有搜到相关文章。
另外,return jiffy这个对应的是clock()吧?

On Sep 4, 2008, at 11:39 AM, Feng Yu wrote:

> linux下简单的gettimeofday系统调用要

redsea

unread,
Sep 4, 2008, 2:05:50 AM9/4/08
to TopLanguage
On Sep 4, 11:43 am, "up duan" <fixo...@gmail.com> wrote:
> UNIX下的驱动模型从理论角度来说还比不上Windows的驱动模型呢。
理论角度 ?
我尝试过写 windows ifs, 太多陷阱了, 看过 smb client (有一个名字, 是 redirector 还是什么,
忘了) 的source code, 很不容易看懂.

linux 就易写很多.

理论恐怕只是 MS 自己说的吧, 只说大概, 让大家都觉得很好, 内幕其实颇不是这么回事. linux open source, 而
且是大家自愿参与开发的, 太 dirty 会遭骂, 而且就没有人愿意参与了.


> UNIX稳定的基本原因是提供的API简单且相对一致,Programmer比较容易搞定怎么做才是对的。而且UNIX出现的时间长,很多问题大家都耳熟能详以至于能够避免了。
> 我的核心观点还是多进程比多线程安全,除非线程附加上了TLS,那又跟多进程差不多了。
> 实际上,现在的并行研究中,基于消息传递【类似于进程的地址空间隔离+IPC】的方式总是比基于共享内存【类似于多线程】的方式在理论上讨人喜欢。

我在学校自己试图写过一个微内核的小 OS kernel, 结果发现, 这种消息传递机制(特别是异步), 调试起来的难度, 比起函数调用的
机制难好多. 后来看到 gnu hurd 老是出不来, 心里就暗想, 会不会和这个有关系.


SevenCat

unread,
Sep 4, 2008, 2:08:20 AM9/4/08
to TopLanguage
商业化的操作系统基本上都是宏内核,微内核可能只有在理论上和一些嵌入式系统中才有用。
理论和实际有不少的差距。很多东东确实只有实践了才知道怎么回事,空洞的看书经常会脱离实际。

莫华枫

unread,
Sep 4, 2008, 2:11:36 AM9/4/08
to pon...@googlegroups.com
曾经对win下的驱动很着迷,到了2000吧,出来了wdm。粗略地了解了一下,好像是以流为核心的模型。看起来酷酷的。具体怎么样,就没有深究。不过从现在对ms的认识来看,还是觉得忽悠的成分多些。或许是偏见吧。:P

2008/9/4 redsea <red...@gmail.com>

redsea

unread,
Sep 4, 2008, 2:23:16 AM9/4/08
to TopLanguage
这个 windows video driver 的历史, 我的记忆是和 wing fire 说的差不多, 和老莫说的不太一致.

redsea

unread,
Sep 4, 2008, 2:40:22 AM9/4/08
to TopLanguage
> 我前面的帖子提到了可以参照Singularity系统,不区分内核和用户这两个地址空间,会让性能提高不少。
> 至于由于少了隔离而导致的安全性下降,可以采用契约化的消息传递来提高,实际上Singularity的可靠性似乎很高。

倾向于理论上更好的东西, 是我在学校以及毕业出来头些年做的事情.

现在要做事情, 只能依赖于已有的系统.

要说不好, x86, x64 这种东西, 无数历史包袱, 就非常差.

莫华枫

unread,
Sep 4, 2008, 2:43:26 AM9/4/08
to pon...@googlegroups.com
我记不清那里看来的,时间太长了。gdi和设备驱动还不完全是一回事,gdi的接口算是高级图形接口。下面扎得很深,就看扎得多深了。好像原本高级图形部分也在ring0里,后来再提出来的。底层与硬件打交道的当然是不可能出来的。好像记得还有那么个图的。
gdi调用频繁,能总穿透ring0性能不行。底层图形接口就相对少一些了。

bwt:nt3.5好象是C2的,4.0以后ms似乎就不理这茬了。

2008/9/4 redsea <red...@gmail.com>

wing fire

unread,
Sep 4, 2008, 3:00:01 AM9/4/08
to pon...@googlegroups.com


2008/9/4 莫华枫 <longsh...@gmail.com>

我记不清那里看来的,时间太长了。gdi和设备驱动还不完全是一回事,gdi的接口算是高级图形接口。下面扎得很深,就看扎得多深了。好像原本高级图形部分也在ring0里,后来再提出来的。底层与硬件打交道的当然是不可能出来的。好像记得还有那么个图的。
gdi调用频繁,能总穿透ring0性能不行。底层图形接口就相对少一些了。

bwt:nt3.5好象是C2的,4.0以后ms似乎就不理这茬了。

没记错的话,NT 4.0有达到C2的,但是,是特别的裁剪版本。那个安全级要求用户代码不能直接访问硬件,那个什么后来,微内核的性能问题越来越多,这个要求早就被打破了,微软从此就不提这个了。不过安全隐患确实很多。

其实GDI的本身的代码慢也有限,主要的瓶颈还是在系统调用上,但这个很难改,因为GDI不仅仅是绘图这一件事。他想定义一个通用绘制层,还要考虑到安全因素,还要兼容各种显示设备,以至于只能用最保守的方式绘图。除非改动这些目标,否则,很难快的起来。

莫华枫

unread,
Sep 4, 2008, 3:06:45 AM9/4/08
to pon...@googlegroups.com


2008/9/4 wing fire <wing...@gmail.com>



2008/9/4 莫华枫 <longsh...@gmail.com>

我记不清那里看来的,时间太长了。gdi和设备驱动还不完全是一回事,gdi的接口算是高级图形接口。下面扎得很深,就看扎得多深了。好像原本高级图形部分也在ring0里,后来再提出来的。底层与硬件打交道的当然是不可能出来的。好像记得还有那么个图的。
gdi调用频繁,能总穿透ring0性能不行。底层图形接口就相对少一些了。

bwt:nt3.5好象是C2的,4.0以后ms似乎就不理这茬了。

没记错的话,NT 4.0有达到C2的,但是,是特别的裁剪版本。那个安全级要求用户代码不能直接访问硬件,那个什么后来,微内核的性能问题越来越多,这个要求早就被打破了,微软从此就不提这个了。不过安全隐患确实很多。
c2是为了糊弄军方吧。


其实GDI的本身的代码慢也有限,主要的瓶颈还是在系统调用上,但这个很难改,因为GDI不仅仅是绘图这一件事。他想定义一个通用绘制层,还要考虑到安全因素,还要兼容各种显示设备,以至于只能用最保守的方式绘图。除非改动这些目标,否则,很难快的起来。
恩,代码在哪儿跑无关紧要,不会差很多。还是调用的代价大。服务抽象也是一个问题。联想到现在的.net,这性能惨不忍睹



2008/9/4 redsea <red...@gmail.com>
这个 windows video driver 的历史, 我的记忆是和 wing fire 说的差不多, 和老莫说的不太一致.


On Sep 4, 11:33 am, "wing fire" <wing.f...@gmail.com> wrote:
> 我怎么记得当初慢是因为微内核的架构呢?GDI最终需要访问硬件,而用户代码是决不能访问硬件的。这是HAL导致的必然结果。微内核的情况下,GDI的最初由特定的service来完成,core负责维持通信,这个开销太大,于是,取消service,直接到到核心。这是我所听到的历史。
> 陷入到ring0虽然慢了点,但是比起微内核的通信还是快多了啊。后来的directX,才是真正的从用户空间直接访问硬件的,因为数据量太大,都通过ring0的话都慢的不行。也因为directX直接访问硬件的这个特性,所以,只要上了directX,好像C2,还是B2什么的安全级就不可能达到了。
> 另外,好像从XP还是2003开始,Audio这样的服务出现在了系统服务中,大概是因为现在机器性能够强,Audio这样开销不太大的功能重新回到微内核的service中去了吧。





--





SevenCat

unread,
Sep 4, 2008, 3:12:19 AM9/4/08
to TopLanguage
ms的gdi系统非常的复杂。win32k.sys的大小是1.8M多,跟ntoskrnl.exe都快差不多了。这还仅仅是内核部分的,还有用户部分
的gdi32.dll(这个应该就是类似于ntoskrnl.exe对应的ntdll.dll了)
win32k.sys好像还是专门用的一个中断表。

On 9月4日, 下午3时06分, "莫华枫" <longshank...@gmail.com> wrote:
> 2008/9/4 wing fire <wing.f...@gmail.com>
>
>
>
> > 2008/9/4 莫华枫 <longshank...@gmail.com>
>
> >> 我记不清那里看来的,时间太长了。gdi和设备驱动还不完全是一回事,gdi的接口算是高级图形接口。下面扎得很深,就看扎得多深了。好像原本高级图形部分也在ring0里,后来再提出来的。底层与硬件打交道的当然是不可能出来的。好像记得还有那么个图的。
> >> gdi调用频繁,能总穿透ring0性能不行。底层图形接口就相对少一些了。
>
> >> bwt:nt3.5好象是C2的,4.0以后ms似乎就不理这茬了。
>
> > 没记错的话,NT
> > 4.0有达到C2的,但是,是特别的裁剪版本。那个安全级要求用户代码不能直接访问硬件,那个什么后来,微内核的性能问题越来越多,这个要求早就被打破了,微软从此就不提这个了。不过安全隐患确实很多。
>
> c2是为了糊弄军方吧。
>
>
>
> > 其实GDI的本身的代码慢也有限,主要的瓶颈还是在系统调用上,但这个很难改,因为GDI不仅仅是绘图这一件事。他想定义一个通用绘制层,还要考虑到安全因素,还要兼容各种显示设备,以至于只能用最保守的方式绘图。除非改动这些目标,否则,很难快的起来。
>
> 恩,代码在哪儿跑无关紧要,不会差很多。还是调用的代价大。服务抽象也是一个问题。联想到现在的.net<http://xn--rcry4j3zjjqtqhdr8s.net>
> ,这性能惨不忍睹
>
>
>
>
>
> >> 2008/9/4 redsea <red...@gmail.com>
>
> >>> 这个 windows video driver 的历史, 我的记忆是和 wing fire 说的差不多, 和老莫说的不太一致.
>
> >>> On Sep 4, 11:33 am, "wing fire" <wing.f...@gmail.com> wrote:
>
> >>> 我怎么记得当初慢是因为微内核的架构呢?GDI最终需要访问硬件,而用户代码是决不能访问硬件的。这是HAL导致的必然结果。微内核的情况下,GDI的最初由特定的service来完成,core负责维持通信,这个开销太大,于是,取消service,直接到到核心。这是我所听到的历史。
>
> >>> 陷入到ring0虽然慢了点,但是比起微内核的通信还是快多了啊。后来的directX,才是真正的从用户空间直接访问硬件的,因为数据量太大,都通过ring0的话都慢的不行。也因为directX直接访问硬件的这个特性,所以,只要上了directX,好像C2,还是B2什么的安全级就不可能达到了。
>
> >>> 另外,好像从XP还是2003开始,Audio这样的服务出现在了系统服务中,大概是因为现在机器性能够强,Audio这样开销不太大的功能重新回到微内核的service中去了吧。
>
> >> --
> >> 反者道之动,弱者道之用
> >> m...@seaskysh.com
> >> longshank...@gmail.com
> >>http://blog.csdn.net/longshanks/
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/

up duan

unread,
Sep 4, 2008, 3:41:12 AM9/4/08
to pon...@googlegroups.com
首先我觉得你们对微内核的印象还是来源于第一代,Mach之类的那种内核,现在的L4不仅仅是理论上比单体内核好,实际上也比单体内核好。

其次,Linux是比Windows的驱动好些的多,但是这并不证明Linux的驱动模型比Windows的驱动模型好,其实反而可能是相反,Windows的驱动模型考虑的更周详和全面,程序员确实需要了解更多的概念和框架才能进入,而Linux却非常直接,所以进入门槛比较低。

我还是坚持认为X比GDI性能低主要原因是X采用UNIX Domain Socket方式交互而Windows采用直接的函数调用。

我知道现实必须面对,但是如果对OS研究方面的成果不闻不问或许也不是面对现实的态度吧。

2008/9/4 SevenCat <BastE...@gmail.com>

SevenCat

unread,
Sep 4, 2008, 3:59:20 AM9/4/08
to TopLanguage
如果你觉得你有道理,可以贴出一些更详细的资料来说服大家,或者用例子OS来证明给大家看。或者你把linux下界面的架构介绍给我们听听,这方面我基
本 上没看过。不知道他是怎么处理的。

On 9月4日, 下午3时41分, "up duan" <fixo...@gmail.com> wrote:
> 首先我觉得你们对微内核的印象还是来源于第一代,Mach之类的那种内核,现在的L4不仅仅是理论上比单体内核好,实际上也比单体内核好。
> 其次,Linux是比Windows的驱动好些的多,但是这并不证明Linux的驱动模型比Windows的驱动模型好,其实反而可能是相反,Windows的驱动模型考虑的更周详和全面,程序员确实需要了解更多的概念和框架才能进入,而Linux却非常直接,所以进入门槛比较低。
>
> 我还是坚持认为X比GDI性能低主要原因是X采用UNIX Domain Socket方式交互而Windows采用直接的函数调用。
>
> 我知道现实必须面对,但是如果对OS研究方面的成果不闻不问或许也不是面对现实的态度吧。
>
> 2008/9/4 SevenCat <BastEt.W...@gmail.com>

avalon

unread,
Sep 4, 2008, 4:44:13 AM9/4/08
to pon...@googlegroups.com
性能低主要是两点:1 驱动架构的问题,2 驱动的问题
ms在和硬件厂商沟通方面做了很多工作,这点Linux下没法比的
模式切换引起的效率低下,属于驱动架构的问题
至于驱动,比如Linux下opengl驱动,除了nv做的还好,其他厂家的
就没法提了。


SevenCat 写道:

莫华枫

unread,
Sep 4, 2008, 5:17:35 AM9/4/08
to pon...@googlegroups.com
以下文字摘自wiki,描述了microkernel的一个优点:
For example, if a networking service crashed due to buffer overflow, only the networking service's memory would be corrupted, leaving the rest of the system still functional. On a traditional monolithic kernel, the overflow could possibly corrupt the memory of other drivers and possibly the kernel itself, which could crash the entire system.

windows现在是microkernal,怎么和这个描述一点都不像啊。:)

2008/9/4 avalon <aval...@gmail.com>

SevenCat

unread,
Sep 4, 2008, 5:19:51 AM9/4/08
to TopLanguage
windows不是微内核。最多只是架构分层分得比较细的宏内核。

On 9月4日, 下午5时17分, "莫华枫" <longshank...@gmail.com> wrote:
> 以下文字摘自wiki,描述了microkernel的一个优点:
> For example, if a networking service crashed due to buffer
> overflow<http://en.wikipedia.org/wiki/Buffer_overflow>,
> only the networking service's memory would be corrupted, leaving the rest of
> the system still functional. On a traditional monolithic kernel, the
> overflow could possibly corrupt the memory of other
> drivers<http://en.wikipedia.org/wiki/Drivers>and possibly the kernel
> itself, which could crash the entire system.
>
> windows现在是microkernal,怎么和这个描述一点都不像啊。:)
>
> 2008/9/4 avalon <avalo...@gmail.com>
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/

up duan

unread,
Sep 4, 2008, 5:24:13 AM9/4/08
to pon...@googlegroups.com
Windows借鉴了MicroKernel,但是很多东西还是塞进内核去了,所以出了问题还是全崩。

2008/9/4 SevenCat <BastE...@gmail.com>

莫华枫

unread,
Sep 4, 2008, 7:23:19 AM9/4/08
to pon...@googlegroups.com
刚才看了一眼nt设备驱动的书,nt的microkernel的确是仿冒的。

2008/9/4 up duan <fix...@gmail.com>

Hongzhang Liu

unread,
Sep 4, 2008, 9:48:00 AM9/4/08
to pon...@googlegroups.com
google user level thread lib,一堆的。fiber只不过是ms提供的一个user level thread 库罢了,需要的话自己实现并不困难。

NT 3.5的时候gdi部分是由csrss.exe进程负责,ms为了尽可能的高效做了很多工作,像fast LPC,对应每个用户线程在csrss.exe中启动一个线程与之配对,然后就是所提到的使用两个未公开的api实现精确的切换,不过性能依然不好,最终在NT 4.0时将gdi部分移入了内核中。

2008/9/4 up duan <fix...@gmail.com>

Hongzhang Liu

unread,
Sep 4, 2008, 9:58:02 AM9/4/08
to pon...@googlegroups.com
L4目前有实际使用的例子吗?

windows中以IRP形式在各个驱动层次之间传递io请求,在这个层次上实现了对异步IO的完美支持,其驱动的分层结构也非常漂亮,说实话我觉得比linux的模型要精致的多。

目前的xorg使用DRI之类的加速技术后,据说性能已经不成问题了,前些天在linuxforum上有过这方面的讨论。不过linux下显卡驱动的质量很成问题。
2008/9/4 up duan <fix...@gmail.com>

Hongzhang Liu

unread,
Sep 4, 2008, 10:08:44 AM9/4/08
to pon...@googlegroups.com
呵呵,IFS应该是windows驱动中最难的部分了,与内核中内存管理、cache管理关联的非常紧,以致于不能使用普通的DDK而必须使用IFS kit才能开发。你一下子就弄到最难的部分,觉得有困难应该是正常的。
普通的WDM驱动程序开发起来应该还是不难的,我用driver studio开发过一个usb host驱动,需要写的代码非常少,三四百行的样子,很爽。
所谓大教堂与集市,NT应该是大教堂的一个杰出代表,经过了精心设计,这么多年了其核心架构基本上保持不变,不得不佩服啊

2008/9/4 redsea <red...@gmail.com>

avalon

unread,
Sep 4, 2008, 10:25:34 AM9/4/08
to pon...@googlegroups.com
driver本什么没什么复杂的,看看ddk短时间也能掌握了
像gdi还好,复杂的是像d3d或者ogl里面的逻辑。
Hongzhang Liu 写道:

莫华枫

unread,
Sep 4, 2008, 8:30:08 PM9/4/08
to pon...@googlegroups.com
证据终于找到了。呵呵,不过是我记错了。 wing fire和Hongzhang Lie是对的。哦,还有readsea:)。移到user mode是另外一个故事。本想把文字拍成照片传上来的,可收集的定焦镜头太差了,没一个字在焦点上,只能一个字一个字地敲了:
在Windows NT的原始设计中一个目标是把制定政策的代码都限制到Win32服务器进程,CSRSS。开发者相信,这会使系统更加牢固,更加易于修改。结果,对许多USER和GDI函数的调用要求与CSRSS进程交互。这是相当昂贵的操作,因为它涉及在Win32客户端与CRSS服务程序之间的环境切换。通过比较(???这是谁翻的!),KERNEL函数可以在调用进程的环境中处理。他们的唯一开销是与内核模式的转换。
这个体系已经在Windows NT 4.0中被替换,这是由于它对基于图形的Win32程序产生性能限制。现在,一个叫做WIN32K.SYS的内核模式组件接管了以前由CSRSS做的大部分工作。采用这种方法,对User和GDI函数的调用可以在调用进程的环境中执行,结果是图形密集的应用程序的速度得到极大的提高。

从这点来看,nt原本也打算microkernel的,但是最终屈服于性能,只能回归传统的模式。microkernel和monolithic kernel也说不清谁好谁坏。性能对于浏览器这样的高端软件都那么重要,更何况操作系统呢。既然monolithic kernel在性能上天生不如microkernel,多数人不理它也是情有可原。

下一个问题:现代monolithic kernel的操作系统在提高稳定性和灵活性方面有没有什么新的方法?

2008/9/4 Hongzhang Liu <hongzh...@gmail.com>

SevenCat

unread,
Sep 4, 2008, 8:34:39 PM9/4/08
to TopLanguage
短时间写个成熟的ifs任何一种驱动基本上都只有天才才能够办得到。HongZhang Liu说得没错,内存管理,cache管理很难理解。
有不少驱动甚至写了两三年都还是有问题。
纯粹写个简单的hello world驱动倒是比较简单。

avalon

unread,
Sep 4, 2008, 9:10:08 PM9/4/08
to pon...@googlegroups.com
没接触过ifs,不好说,我了解些display方面东西,display driver结构本身不复杂,
这东西就好比语言,化上1,2个月就可以上手了,真正难得是内部复杂的逻辑,
软件和硬件逻辑,搞上几年也未必敢说自己都了解了。

SevenCat 写道:

Mingxi Wu

unread,
Sep 4, 2008, 9:41:36 PM9/4/08
to pon...@googlegroups.com


2008/9/4 up duan <fix...@gmail.com>

首先我觉得你们对微内核的印象还是来源于第一代,Mach之类的那种内核,现在的L4不仅仅是理论上比单体内核好,实际上也比单体内核好。

其次,Linux是比Windows的驱动好些的多,但是这并不证明Linux的驱动模型比Windows的驱动模型好,其实反而可能是相反,Windows的驱动模型考虑的更周详和全面,程序员确实需要了解更多的概念和框架才能进入,而Linux却非常直接,所以进入门槛比较低。

我还是坚持认为X比GDI性能低主要原因是X采用UNIX Domain Socket方式交互而Windows采用直接的函数调用。

X的IPC不会影响太多性能。
IPC是GUI系统的必然选择。Win的GDI底层也必然是有IPC的,只不过它是以函数的形式暴露给你。

因为GUI系统实际上是许多应用程序 _共享_ 整个图形资源, 并且之间还有很多交互,所以使用CS架构来管理是再自然不过的思路了。

举一个最典型的例子就是Window Manager, 所有application的titlebar实际上并不属于application本身,而是属于Window Manager, 用户点击 最大化, 最小化这样的按钮,产生的结果是Window Manager给application发送一个最大化的消息。这样的例子太多了,IPC在GUI系统中简直是无处不在的。

X比GDI性能低有任何可参考测试数据么?

说短处,X的driver是比Win差了许多,毕竟没有商业支持。
然后就是Win的鼠标系统做的好, GDI早挂了,鼠标还一点没延迟跑得溜快,给人一种假象。

 

up duan

unread,
Sep 5, 2008, 1:45:05 AM9/5/08
to pon...@googlegroups.com
WindowsGDI下层不是IPC方式的呀。有证据证明吗?
Windows现在的显卡驱动模型叫做WDDM什么的,把很多原来认为应该是图形显示逻辑层的东西嵌入到驱动层去了,极大的提高了显示性能。据称,由于还要通过Windows的硬件驱动认证,可靠性也提高了不少。驱动模型本身分成两个层次,一个是内核层的KDM,另一个是执行密集显示逻辑运算的用户层。

X性能低于Windows是公认的吧。由于X采用Socket方式通信,而且只提供了120个原语,一个简单的显示逻辑的执行可能就需要数个XProtocol交互,而Windows提供了虽然不规整但是很全面的API,很多常用的操作只需要一次交互。估计这也是X性能低的部分原因。

2008/9/5 Mingxi Wu <feng...@gmail.com>

Jiahua Huang

unread,
Sep 5, 2008, 3:06:26 AM9/5/08
to pon...@googlegroups.com
On 9/5/08, up duan <fix...@gmail.com> wrote:
> X性能低于Windows是公认的吧。由于X采用Socket方式通信,

现在 X 可用的 dri、xshm、xv、gl 这些呢?

Mingxi Wu

unread,
Sep 5, 2008, 3:26:28 AM9/5/08
to pon...@googlegroups.com


2008/9/5 up duan <fix...@gmail.com>
WindowsGDI下层不是IPC方式的呀。有证据证明吗?
我倒真没有证据,谁要MS没有开源呢?

不过,请考虑一个问题, 站在整个桌面环境而不是单个应用程序的角度,所有应用程序 _共享_ 整个图形资源,并且它们还和 桌面环境有相当多的交互。它们必须把自己的一些信息暴露给桌面环境以方便统一管理,不用IPC,用什么呢?
 

up duan

unread,
Sep 5, 2008, 3:30:13 AM9/5/08
to pon...@googlegroups.com
DRI是直面XProtocol问题并试图解决的一个尝试,XShm采用了另一个模式试图解决这个问题,但是我觉得会变得跟Windows的方案差不多。xv和gl是指?
但是无论如何,这些方案都改变了X的构想。

2008/9/5 Jiahua Huang <jhuang...@gmail.com>

up duan

unread,
Sep 5, 2008, 3:34:02 AM9/5/08
to pon...@googlegroups.com
DestopManager和DisplayDriver是两个层次吧。
图形资源是由DisplayDriver处理【管理】的。
说Windows性能高过X,主要是指其DisplayDriver层次的,而不是DestopManager层次的。
另外,DisplayDriver比VideoCardDriver高一个层次。

2008/9/5 up duan <fix...@gmail.com>

Mingxi Wu

unread,
Sep 5, 2008, 3:51:14 AM9/5/08
to pon...@googlegroups.com


2008/9/5 up duan <fix...@gmail.com>

DestopManager和DisplayDriver是两个层次吧。
图形资源是由DisplayDriver处理【管理】的。
说Windows性能高过X,主要是指其DisplayDriver层次的,而不是DestopManager层次的。

那么, X的IPC机制正是DesktopManager层次,在DisplayDriver之上,所以IPC不是主要的性能瓶颈。

xv是xvideo
gl是opengl

pi1ot

unread,
Sep 5, 2008, 3:54:30 AM9/5/08
to TopLanguage
这是什么书,那本the old new thing上没看到啊

On Sep 5, 8:30 am, "莫华枫" <longshank...@gmail.com> wrote:
> 证据终于找到了。呵呵,不过是我记错了。 wing fire和Hongzhang Lie是对的。哦,还有readsea:)。移到user
> mode是另外一个故事。本想把文字拍成照片传上来的,可收集的定焦镜头太差了,没一个字在焦点上,只能一个字一个字地敲了:
> 在Windows
> NT的原始设计中一个目标是把制定政策的代码都限制到Win32服务器进程,CSRSS。开发者相信,这会使系统更加牢固,更加易于修改。结果,对许多USER-和GDI函数的调用要求与CSRSS进程交互。这是相当昂贵的操作,因为它涉及在Win32客户端与CRSS服务程序之间的环境切换。通过比较(???这是谁翻-的!),KERNEL函数可以在调用进程的环境中处理。他们的唯一开销是与内核模式的转换。
> 这个体系已经在Windows NT
> 4.0中被替换,这是由于它对基于图形的Win32程序产生性能限制。现在,一个叫做WIN32K.SYS的内核模式组件接管了以前由CSRSS做的大部分工作-。采用这种方法,对User和GDI函数的调用可以在调用进程的环境中执行,结果是图形密集的应用程序的速度得到极大的提高。
>
> 从这点来看,nt原本也打算microkernel的,但是最终屈服于性能,只能回归传统的模式。microkernel和monolithic
> kernel也说不清谁好谁坏。性能对于浏览器这样的高端软件都那么重要,更何况操作系统呢。既然monolithic
> kernel在性能上天生不如microkernel,多数人不理它也是情有可原。
>
> 下一个问题:现代monolithic kernel的操作系统在提高稳定性和灵活性方面有没有什么新的方法?
>
> 2008/9/4 Hongzhang Liu <hongzhang....@gmail.com>
>
>
>
>
>
> > google user level thread lib,一堆的。fiber只不过是ms提供的一个user level thread
> > 库罢了,需要的话自己实现并不困难。
>
> > NT 3.5的时候gdi部分是由csrss.exe进程负责,ms为了尽可能的高效做了很多工作,像fast
> > LPC,对应每个用户线程在csrss.exe中启动一个线程与之配对,然后就是所提到的使用两个未公开的api实现精确的切换,不过性能依然不好,最终在NT
> > 4.0时将gdi部分移入了内核中。
>
> > 2008/9/4 up duan <fixo...@gmail.com>
>
> > 整个都不知道跑题到哪儿了。
>
> >> 首先我能确定,Windows现在的GDI是在KernelSpace里面的。
>
> >> 对于Linux下实现Fiber,你给出个提示吧。Fiber的切换就完全是程序控制的,而不是Kernel控制的,这还不是让你自己控制切换?
>
> >> 现在大多数系统都只是用了Ring0和Ring3,对于现在的VMWare,Xen等虚拟机,Intel和AMD不约而同的增强了Ring1下的指令以便于支持-高性能的多系统切换。
>
> >> 2008/9/4 Hongzhang Liu <hongzhang....@gmail.com>
>
> >> 纤程 fiber
> >>> 不过是用户级线程而已,在linux下照样可以实现出来。windows中也不存在保证切换到某个特定线程的方法;undocumented
> >>> NT中提到nt为了GDI实现的高效,使用了两个未公开的API来实现一对线程之间的切换,不过并没有开放给应用程序使用。
>
> >>> 2008/9/3 up duan <fixo...@gmail.com>
>
> >>>> 就我所知,主动切换的在Windows下面不叫线程,叫纤程。Linux下没有什么办法能够控制Thread的切换,你只能在时间片内部自己出让,但是不能保证-一定会给自己所拥有的另一个线程。
>
> >>>> 2008/9/3 redsea <red...@gmail.com>
>
> >>>>> kernel level 为什么要等 timer event 切换 ? kernel thread 一样可以主动切换.
>
> >>>>> 你想说的是, 懂得领域知识的 Scheduler 比通用的 schedule 好吧 ?
>
> >>>>> 你转移论题了.
>
> >>>>> 你在 kernel space 写程序, 也可以自己 schedule 啊.
>
> >>>>> On Sep 3, 4:26 pm, "up duan" <fixo...@gmail.com> wrote:
> >>>>> > >Activation
>
> >>>>> Scheduler里面的说法是Kernel级别需要考虑各种通用情形,并且Kernel没有User级别对于该App所关心的领域具有的特定知识。>比如Us-er
> >>>>> > Level的调度是在需要的时候进行,而Kernel Level的调度是在Timer
> >>>>> Event到达的时候进行,所以Kernel的慢。而且这个慢不可逾越。
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/

Jiahua Huang

unread,
Sep 5, 2008, 4:34:52 AM9/5/08
to pon...@googlegroups.com
On 9/5/08, up duan <fix...@gmail.com> wrote:
> 但是无论如何,这些方案都改变了X的构想。
>

人们在用的,都是你所谓"改变了构想的 X",或说"作弊"的高性能的 Xorg。

而你"纯粹"的,性能低于 Windows 的 X ,是没人用的。

up duan

unread,
Sep 5, 2008, 4:45:07 AM9/5/08
to pon...@googlegroups.com
o,我真的不知道啊。我google了一下,发现了一些说是怎么开启DRI的方法,我想这似乎也说明了很多人都不知道怎么开启DRI吧。

嗯,X现在确实正在提高自己的性能。应该已经不比Windows的性能低下了。

2008/9/5 Jiahua Huang <jhuang...@gmail.com>

Jiahua Huang

unread,
Sep 5, 2008, 4:53:05 AM9/5/08
to pon...@googlegroups.com
On 9/5/08, up duan <fix...@gmail.com> wrote:
> o,我真的不知道啊。我google了一下,发现了一些说是怎么开启DRI的方法,我想这似乎也说明了很多人都不知道怎么开启DRI吧。
>

Intel、ATI 的显卡驱动都是依据 DRI 的
http://dri.freedesktop.org/wiki/

像 Ubuntu 的 Xorg 在多数 Intel 显卡和部分 ATI/AMD 显卡上都是默认开启了 DRI 的。

而 RHEL 之类应该默认没有。

lbaby

unread,
Sep 5, 2008, 5:08:44 AM9/5/08
to TopLanguage
MINIX是micro core 的

On 9月4日, 上午11时43分, "up duan" <fixo...@gmail.com> wrote:
> UNIX下的驱动模型从理论角度来说还比不上Windows的驱动模型呢。
> UNIX稳定的基本原因是提供的API简单且相对一致,Programmer比较容易搞定怎么做才是对的。而且UNIX出现的时间长,很多问题大家都耳熟能详以至于能够避免了。
> 我的核心观点还是多进程比多线程安全,除非线程附加上了TLS,那又跟多进程差不多了。
> 实际上,现在的并行研究中,基于消息传递【类似于进程的地址空间隔离+IPC】的方式总是比基于共享内存【类似于多线程】的方式在理论上讨人喜欢。
>
> 2008/9/4 wing fire <wing.f...@gmail.com>
>
>
>
> > 2008/9/3 莫华枫 <longshank...@gmail.com>
>
> >> 回家翻了一下书,故事是这样的。
> >> 保护级别0最高,3最低。操作系统核心工作在0上,用户程序工作在3上。如果用户程序想要得到系统服务,必须call
> >> ring0上的代码。但是保护系统规定,低级别的代码不能直接call高级别的代码,也不能访问高级别的数据。否则,用户程序便可以随便访问核心的代码和数据了。为了完成ring3到ring0的call,cpu提供了"门"的机制。切换门以及相关的环境状态(一堆寄存器)需要开销。gdi属于访问频繁的服务,对程序性能影响很大。放在ring0里,每次调用都需要切换cpu保护状态,开销甚大。nt3.5是ms第一种真正完全利用了intel保护模式的操作系统。结果发现图形性能很差。应用程序只能在ring3中执行,无法搬进ring0,那么只能将图形处理部分分离出来,放进ring3。进而在nt4.0之后,将gdi移到ring3,以提高性能。代价就是可靠性变差。
>
> >> 呵呵,还是redsea说的对。:)
> >> 关于指令,我记反了,很多指令在ring3下会引发0D中断。比如cli,int等等。
>
> >> 另外,我也问个问题:在win32下,通常应用程序的非法操作不会引发整个操作系统的崩溃。但如果在kernal
> >> mode中的驱动程序存在非法操作,基本上就出蓝屏了。但我听说在unix中,一般设备驱动出现问题,也不会引发整个操作系统的崩溃。不知是真是假?
> >> 如果是真的,unix采用了什么样的方法做到的呢?
>
> > 这个好像没这么强,估计要看什么设备了。以前整过串口卡,很老的scci卡,照样死。还有热拔插硬盘,你拔光了试试,立马panic。
>
> >> 2008/9/3 莫华枫 <longshank...@gmail.com>
>
> >>> 不是说指令性能差,而是在保护级别的作用下,很多指令是无法在ring0下直接运行的,比如cli会引发异常中断
>
> >>> 2008/9/3 redsea <red...@gmail.com>
>
> >>> 内核态程序不存在性能比用户态差的问题.
>
> >>>> 执行普通的指令(mov, 不缺页), ring0 的性能和 ring3 没有区别.
>
> >>>> 在某些特殊的 context, 例如硬中断, 访问缺页的地址, 系统应该是立刻 panic.
>
> >>>> process context (就是 process 调用系统调用进行内核态, 例如调用 C 程序调用fread, 然后调用 read 进入
> >>>> 内核), 碰到缺页, 和userspace 一样, 引发换页.
>
> >>>> 说系统调用性能差主要的原因是系统调用这个 API 性能差:
> >>>> 1. 要切换部分 CPU 页表, 以便可以访问内核空间
> >>>> 我不知道这里 cache 是否起作用, 如果 cache 不起作用, 纯粹从内存读, 性能影响很大
> >>>> 2. 调用系统调用, 不像普通函数调用, 将参数压栈, 然后 call 就可以了, 而是要准备系统调用的描述结构, 指明要调用那个调用, 然后
> >>>> 将参数复制到一个内核可以访问的空间, 然后执行一个 trap.
> >>>> 这里面有内存复制, 性能也差.
> >>>> 对于 read 这样的调用, 返回值在 buffer 中, 倒一般不必再进行内容复制, 而是调用的时候, 对 buffer 进行
> >>>> memory manger 部分的调用, 获取一个内核态可以访问这个地址的指针, 让内核程序可以直接将结果写到最终的内容中去.
>
> >>>> 总结, 做一个系统调用, 比一个函数调用要做的事情多很多, 所以性能差.
>
> >>>> On Sep 3, 2:01 pm, "莫华枫" <longshank...@gmail.com> wrote:
> >>>> > 通常kernel space的保护级别是0,user
> >>>> > space则用低级别,通常为3(intel)。在ring0里的保护性检测多得多,引发的异常中断也多得多,性能也就差很多。

lbaby

unread,
Sep 5, 2008, 5:11:34 AM9/5/08
to TopLanguage
X 比GDI性能低的原因不在于 SOCKET ,而在于GDI是内核级运行的


On 9月4日, 下午3时41分, "up duan" <fixo...@gmail.com> wrote:
> 首先我觉得你们对微内核的印象还是来源于第一代,Mach之类的那种内核,现在的L4不仅仅是理论上比单体内核好,实际上也比单体内核好。
> 其次,Linux是比Windows的驱动好些的多,但是这并不证明Linux的驱动模型比Windows的驱动模型好,其实反而可能是相反,Windows的驱动模型考虑的更周详和全面,程序员确实需要了解更多的概念和框架才能进入,而Linux却非常直接,所以进入门槛比较低。
>
> 我还是坚持认为X比GDI性能低主要原因是X采用UNIX Domain Socket方式交互而Windows采用直接的函数调用。
>
> 我知道现实必须面对,但是如果对OS研究方面的成果不闻不问或许也不是面对现实的态度吧。
>
> 2008/9/4 SevenCat <BastEt.W...@gmail.com>
>
> > ms的gdi系统非常的复杂。win32k.sys的大小是1.8M多,跟ntoskrnl.exe都快差不多了。这还仅仅是内核部分的,还有用户部分
> > 的gdi32.dll(这个应该就是类似于ntoskrnl.exe对应的ntdll.dll了)
> > win32k.sys好像还是专门用的一个中断表。
>
> > On 9月4日, 下午3时06分, "莫华枫" <longshank...@gmail.com> wrote:
> > > 2008/9/4 wing fire <wing.f...@gmail.com>
>
> > > > 2008/9/4 莫华枫 <longshank...@gmail.com>
>
> > 我记不清那里看来的,时间太长了。gdi和设备驱动还不完全是一回事,gdi的接口算是高级图形接口。下面扎得很深,就看扎得多深了。好像原本高级图形部分也在ring0里,后来再提出来的。底层与硬件打交道的当然是不可能出来的。好像记得还有那么个图的。
> > > >> gdi调用频繁,能总穿透ring0性能不行。底层图形接口就相对少一些了。
>
> > > >> bwt:nt3.5好象是C2的,4.0以后ms似乎就不理这茬了。
>
> > > > 没记错的话,NT
>
> > 4.0有达到C2的,但是,是特别的裁剪版本。那个安全级要求用户代码不能直接访问硬件,那个什么后来,微内核的性能问题越来越多,这个要求早就被打破了,微软从此就不提这个了。不过安全隐患确实很多。
>
> > > c2是为了糊弄军方吧。
>
> > 其实GDI的本身的代码慢也有限,主要的瓶颈还是在系统调用上,但这个很难改,因为GDI不仅仅是绘图这一件事。他想定义一个通用绘制层,还要考虑到安全因素,还要兼容各种显示设备,以至于只能用最保守的方式绘图。除非改动这些目标,否则,很难快的起来。
>
> > > 恩,代码在哪儿跑无关紧要,不会差很多。还是调用的代价大。服务抽象也是一个问题。联想到现在的.net<http://xn--rcry4j3zjjqtqhdr8s.net>
> > <http://xn--rcry4j3zjjqtqhdr8s.net>
> > > ,这性能惨不忍睹
>
> > > >> 2008/9/4 redsea <red...@gmail.com>
>
> > > >>> 这个 windows video driver 的历史, 我的记忆是和 wing fire 说的差不多, 和老莫说的不太一致.
>
> > > >>> On Sep 4, 11:33 am, "wing fire" <wing.f...@gmail.com> wrote:
>
> > 我怎么记得当初慢是因为微内核的架构呢?GDI最终需要访问硬件,而用户代码是决不能访问硬件的。这是HAL导致的必然结果。微内核的情况下,GDI的最初由特定的service来完成,core负责维持通信,这个开销太大,于是,取消service,直接到到核心。这是我所听到的历史。
>
> > 陷入到ring0虽然慢了点,但是比起微内核的通信还是快多了啊。后来的directX,才是真正的从用户空间直接访问硬件的,因为数据量太大,都通过ring0的话都慢的不行。也因为directX直接访问硬件的这个特性,所以,只要上了directX,好像C2,还是B2什么的安全级就不可能达到了。
>
> > 另外,好像从XP还是2003开始,Audio这样的服务出现在了系统服务中,大概是因为现在机器性能够强,Audio这样开销不太大的功能重新回到微内核的service中去了吧。
>

redsea

unread,
Sep 5, 2008, 5:32:02 AM9/5/08
to TopLanguage
现代操作系统, 是指最近一些年开始实现的操作系统, 例如 plan 9, 以及 up duan 让我知道的 Singularity, 还是指现
在广泛在用的 win/linux/bsd ?

前者我是不懂的.

linux 最近一些年在工程管理上面有不小进步, OS 思想我想没有什么变化吧.

windows 就尽在折腾一些外在的东西.

> 下一个问题:现代monolithic kernel的操作系统在提高稳定性和灵活性方面有没有什么新的方法?

up duan

unread,
Sep 5, 2008, 6:01:50 AM9/5/08
to pon...@googlegroups.com
>X 比GDI性能低的原因不在于 SOCKET ,而在于GDI是内核级运行的
我觉得那不是关键,因为应用到显示毕竟都要经过userspace<->kernelspace的切换,不管下层的DisplayDriver是在内核还是在用户空间。

2008/9/5 redsea <red...@gmail.com>
Reply all
Reply to author
Forward
0 new messages