OCZ Synapse Cache——打造你的台式机三级存储架构

今天在网上搜索的时候,在想这么一个问题。目前来看呢,SSD 价格太贵,如果要想买到心满意足的容量呢,要花不少米。但 HDD 的速度还是不是太快,特别当玩过极品飞车以后更觉得其速度只有自行车。

那么有没有折衷的过渡方案呢?于是在网上搜索将 SSD 作为缓存的办法。出乎意料,真的搜到了这么一个方案:OCZ 的 Synapse Cache 系列 SSD,它的容量不大,64GB 和 128GB,但是可以通过它的 DataPlex 软件,用作 HDD 的缓存。

使用起来相当方便。只要把它连接到机器的 SATA3 口上,在你的 Windows 7 系统(32 位或 64 位)上安装一下 DataPlex 软件并配置一下就可以了。SSD 的一半容量将用于缓存,另一半容量作为超规容量(over provisioning),但这个数字已经远比你的物理内存容量大了吧。

这样一来,大量数据将通过缓存读写,速度肯定比 ReadyBoost 还要快。

当然,SSD 的速度相比物理内存还是有差距的。但是有足够的物理内存的前提下再加个 SSD 缓存,就是快马加鞭了。

要是高兴尝试的话,试一试吧。

另:今天还搜到另一解决方案——英特尔智能响应技术,参见http://diy.pconline.com.cn/cpu/reviews/1105/2420920.html

Windows Vista: Cached Reading of a File Opened with No Cache Enabled

Below are my observation regarding the behavior of randomly reading a file without disk cache.

Question 1: why ReadyBoost cache hit rate raises when reading a file (opened with no cache) randomly?

Answer: from what I observed, it is because ReadyBoost does cache the file, even if it is opened with a flag saying no cache is needed.

Question 2: why the file is opened with no cache enabled, but is still read without much disk activity when it is read the second time?

Answer: from what I observed, it is because not only ReadyBoost, but also RAM is used to cache the file, even if it is opened with a flag saying no cache is needed. One evidence is that at first the ReadyBoost hit read bytes becomes higher during the read, and later I ran it more times the ReadyBoost hit read bytes doesn’t become high any more; instead it is finished quickly without much disk activity.

Question 3: does Superfetch work for files that are opened with no cache enabled?

Answer: I think yes. Otherwise there would be no reason that ReadyBoost can cache the file–ReadyBoost needs Superfetch to populate the data.

Question 4: is Windows Vista different from previous versions of Windows?

Answer: As I compared with Windows 2000 (although running inside VPC, but I can observe the virtual HDD light), Windows 2000 doesn’t do any caching to the file if it is opened with the no cache flag.

Question 5: can it be the hard disk drive built-in cache that caches the data for the process reading a file with the no cache flag?

Answer: no. Because I also tried randomly reading 400MB data, which is signifcantly larger than the HDD built-in cache, but it is still cached. So I think the answer is no.

See also my test programs randreadtest.cs, randreadtest_ca.cs and randreadtest_big.cs.

using System;
using System.IO;
using System.Runtime.InteropServices;
namespace RobbieTests
{
    public class NativeMethods
    {
        [DllImport("Kernel32.dll", SetLastError = true)]
        public static extern IntPtr
            CreateFile(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode, IntPtr lpSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer,
           UInt32 nNumberOfBytesToRead, out UInt32 lpNumberOfBytesRead, IntPtr lpOverlapped);
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseHandle(IntPtr hObject);
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern UInt32 SetFilePointer(
            [In] /*SafeFileHandle*/ IntPtr hFile,
            [In] Int32 lDistanceToMove,
            [In, Out] ref Int32 lpDistanceToMoveHigh,
            [In] UInt32 dwMoveMethod);
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern UInt32 SetFilePointer(
            [In] /*SafeFileHandle*/ IntPtr hFile,
            [In] Int32 lDistanceToMove,
            [In] IntPtr lpDistanceToMoveHigh,
            [In] UInt32 dwMoveMethod);
        public static IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
        public static UInt32 GENERIC_READ = 0×80000000;
        public static UInt32 FILE_SHARE_READ = 0×00000001;
        public static UInt32 FILE_SHARE_WRITE = 0×00000002;
        public static UInt32 OPEN_EXISTING = 0×00000003;
        public static UInt32 FILE_ATTRIBUTE_NORMAL = 0×00000080;
        public static UInt32 FILE_FLAG_NO_BUFFERING = 0×20000000;
        public static UInt32 FILE_BEGIN = 0×00000000;
        public static UInt32 INVALID_SET_FILE_POINTER = 0xFFFFFFFF;
    }
    public class RandReadTest /* random uncached read test */
    {
        public static void Main(string[] args)
        {
            const int BUFSIZE = 4096;
            const int MAXBLOCKCNT = 10240;
            IntPtr hFile = NativeMethods.INVALID_HANDLE_VALUE;
            Random rand = new Random();
            byte[] buffer = new byte[BUFSIZE];
            UInt32 sizeread;
            int i;
            try {
                hFile =
                    NativeMethods.CreateFile(args[0], NativeMethods.GENERIC_READ, NativeMethods.FILE_SHARE_READ | NativeMethods.FILE_SHARE_WRITE,
                    IntPtr.Zero, NativeMethods.OPEN_EXISTING,
                    NativeMethods.FILE_ATTRIBUTE_NORMAL | NativeMethods.FILE_FLAG_NO_BUFFERING, IntPtr.Zero);
                if (hFile == NativeMethods.INVALID_HANDLE_VALUE) {
                    throw new FormatException(“Unable to open the file.”);
                }
                for (i = 0; i < MAXBLOCKCNT; i++) {
                    if (NativeMethods.SetFilePointer(hFile, rand.Next(MAXBLOCKCNT) * BUFSIZE, IntPtr.Zero, NativeMethods.FILE_BEGIN) == NativeMethods.INVALID_SET_FILE_POINTER) {
                        throw new FormatException(“Unable to seek in the file.”);
                    }
                    if (!NativeMethods.ReadFile(hFile, buffer, BUFSIZE, out sizeread, IntPtr.Zero)) {
                        throw new FormatException(“Unable to read the file.”);
                    }
                }
            } catch (Exception ex) {
                Console.WriteLine(ex);
                Console.WriteLine(ex.StackTrace);
            } finally {
                if (hFile != NativeMethods.INVALID_HANDLE_VALUE) {
                    NativeMethods.CloseHandle(hFile);
                }
            }
        }
    }
}

[转]社会学家大战外星人——论《三体》中的“宇宙社会学”

按:今天看三体II看得有点疯狂,转一篇贴子和它的一篇回复来看看。

http://book.douban.com/review/2019571/

2009-05-10 20:52:59   来自: 风间隼 (《红毛》中字翻译进行时)
三体Ⅱ的评论

这学期捞到个机会给本科生开社会学导论课,本没指望他们读什么参考书目,不过更没想到的是,我自己反而被布置了两本“课外读物”。

事情是这样,一天下课,一位好心的学生向我推荐说:“老师,你该读一下《三体》,里面提到了一种‘宇宙社会学’!”

“宇宙社会学!”我当时就震撼了!直接想起了朱海军的“面对面”和网上某社会学爱好者发明的“人生论”等等山寨社会学理论,不过这个名词象个黑洞一样,听起来更加具有诱惑力。联想起众多朋友的推荐,我没有理由拒绝相信这是一本好小说。于是诚心诚意地借了来攻读之。

书很好看,“宇宙社会学”出现在刘慈欣“地球往事”三部曲之二——《三体:黑暗森林》里面,主人公罗辑依靠“社会学知识”而非物理学知识战胜了外星人,在公众对社会学认识度不高的当今中国,一部“硬科幻代表作”中把社会学提到这样的高度,很出乎我的意料。

作为一名跨世纪的“社会青年”,总免不了被问到的两个“终极问题”之一就是“社会学有什么用啊?”我以往储备的答案比较低调,比较无厘头:“学了社会学可以教社会学啊!”,令闻者侧目。现在,我知道我可以抛出一个高调得多的答案了:“学了社会学至少可以保卫地球,大战外星人啊!”作为一个业余的(伪)科幻迷来说,这个答案简直太拉风,太合我的心意了!我要向大刘老师致以崇高的敬礼!

不过敬礼归敬礼,这个“宇宙社会学”还是要从专业角度好好考察一下的。“科学幻想”一直把“社会科学”排除在外,其实是个不正常的现象。除了社会科学“准科学”的尴尬地位之外,其实也跟科学界对社会科学研究的特殊性认识不足有关。借这个考察“宇宙社会学”的机会,或许可以看一下,社会科学的专业知识对于丰富我们对未来世界的幻想起着多么重要的作用。而缺了这个视角,对于一部幻想人类未来的小说来说又是多么大的遗憾。

我们知道,知识的建立有两个途径,经验归纳和理论推导(演绎)。经验归纳服从实证批判,理论推导服从逻辑批评。而理论推导必须要有起点,归根结底要建立在经验归纳基础上的。所谓“公理”,是理论的基础,往往是在一定普遍的尺度上不证自明的常识。所以从原则上说,经验世界是所有知识的来源,公理也不例外。公理阶段的偏差,往往直接影响到理论是否正确,或者至少是理论适用的范围大小。

那我们就来看看在杨冬墓前,叶文洁传授给罗辑的宇宙社会学知识,有几分站得住脚。说实话,这一幕总让我联想到上帝向摩西显现。

宇宙社会学第一公理:生存是文明的第一需要。

宇宙社会学第二公理:文明不断增长和扩张,但宇宙中的物质总量保持不变。

罗辑说:“叶老师,从社会学角度看,这两条公理都足够坚实……”

很遗憾,从社会学角度看,这两条公理都不成立。

先说第一条。逻辑学上,“是”是个极其关键的词汇,“应然”或是“实然”都可以用“是”来表达,但其中的含义是截然不同的。第一公理这个命题,是“应然”还是“实然”呢?“生存应该成为文明的第一需要?”还是“生存确实是文明的第一需要?”

大刘在这两本经天纬地的奇书中已经展现出了他深厚的自然科学素养。但是对于社会科学,他显然没有把握住其中的关键。前面提到社会科学的特殊性,在我看来,就是“意义”二字。原因无他,因为社会科学研究的现象无论再怎样被“忽略细节,浓缩成一个点”,面对的集合体也是由有意志有情感的个人组成的。涉及人的地方,一定存在意义。宇宙社会学第一公理到底是应然命题还是实然命题,这在自然科学中无足轻重。因为恒星和原子是不会涉及意义的。无论“应该这样转”还是“确实这样转”对它们来说都是一样,总之他们就是这样转。但是对于人类文明来说,情况完全不同。

人有意志,可以选择,而且他们的选择并不总是依据自己真正的需要,哪怕是学者眼中的“第一需要”!现代社会的“成瘾性”现象就不必说了,古人的事例更是多不胜数。不必烦引现象学社会学的理论,简单举例即可。古龙说过一句话:“每个人都有一样比自己的命更要紧的东西,酒鬼眼中的酒,色鬼眼中的美人,赌鬼眼中的赌局,都是如此。”其实已经把这个道理说得很清楚。人之所以为人,正因为他并不像动物一般,把自己的生命看得重于一切。谈论到“文明”,尤其如此。“文明”必然涉及“互惠”和“利他”,有时候,生存的第一需要也是可以被牺牲的。

当然人有为了基本生存不惜一切的时候,社会学从来不否认这一点。但是作为“公理”,应该是个极强的论断,只要有反证就可以被推翻,何况是如此大量的“反证”。只能说这个公理本身有问题。

假设宇宙社会学的对手辩驳:“不,你说的是微观层次,作为整个文明本身,是不会为了另一个文明牺牲的。”

我同意,但是既然上升到宏观层次,我就要提醒对手,他在摆脱了一个问题的同时,面对着一个新的问题:文明本身是有重量的。

这个诗意的说法借自卡尔维诺的《看不见的城市》,用社会学术语来说,文明社会必然是个分化的社会,其运行是有成本的。生存的需要并不必然可以清晰地传递到决定文明命运的阶层心中。如果从“生存是第一需要”的公理出发,五世纪的罗马帝国应该重整尚武精神,把蛮族迁移到边疆才对,不应该大量雇用蛮族军队。清王朝末年应该整顿吏治,推行新政才对,不该把施行宪政的日期一推再推。可惜我们知道这一切都没有机会发生,有权力为文明选择未来的人往往已经被文明局限住了视野,一个文明运行的成本决定了它无力去选择另一种可能。

用一个诗化的说法总结就是:“文明自身是自身的敌人”。探寻历史上文明盛衰的轨迹,无不如此,所以说,无论“应然”还是“实然”,第一公理都是站不住脚的。

宇宙社会学第二公理不成立的原因,和第一条有联系。

宇宙中总量保持恒定与否和社会学没关系,可以省略,重点看前半句。

如今地球上生存的人,总属于这种或那种文明,所以当我们回顾文明的历程时,总不免产生“文明在不断增长和扩张”的幻想。可事实呢?地球上曾经存在过的所有文明中,延续到今天的绝对是少数。大多数文明都已经湮没在历史的长河中了。王铭铭在碰到有人质疑历史的重要性时,总要反问对方:“你说自古到今,死人多还是活人多?”面对宇宙社会学第二公理,我们可以这么问,只不过主体换成文明而已:消失的文明多还是延续下来的文明多?

假设我的对手这样辩驳:“你说的这都是地球上的状况,宇宙中不适用!”并且引用创始人叶文洁的话:“宇宙社会学比起人类社会学来呈现出更清晰的数学结构!”

对不起,还是不对。人群的量级是个问题,不过不是核心的问题。哪怕在一个社会内部,只要从统计入手,大量社会事实也会呈现出清晰的数学结构,例如离婚率、自杀率、教派人数兴衰等等,并不需要放大到宇宙级别。问题是你采取什么路径去看。坚持实证方法,用自然科学手段研究社会的人,也会得到一些成果,但是从概念界定开始(什么叫做“婚姻”和“教派”),他就会遭到“意义”问题的持续困扰,直到他解释这些现象为止(为什么离婚率会上升?为什么教派兴起又衰落?)。他会发现数学可以帮他一些忙,但是关键的问题他都必须从意义入手才能解决。照《三体》的世界观看,三体人或许比较先进,比较特殊(不能隐藏内心意图),但是与人类一样有精神觉悟,有自由意志的生物,能制造、交流和读解意义。宇宙中的其他文明数量再多,构成的“宇宙社会”再复杂,只要能互相交流,那么“宇宙社会学”就一定会涉及到意义问题,绝对不可能用数学来解决的。

所以说穿了,所谓“宇宙社会学有清晰的数学结构”,其实只是理工科背景人士对于社会的一种幻想(不客气地说是无知),跟宇宙不宇宙倒没什么关系。

接下来谈谈两个重要概念:“猜疑链”和“技术爆炸”。

猜疑链不新鲜,博弈论中的“囚徒困境”就是典型的猜疑链造成的——两个囚徒互相猜疑对方的选择,难以决定自己的下一步如何举措。这个假设的前提是两人处于完全无知的黑幕状态,并且彼此之间缺乏信任和共同利益。

这个假设听起来没错,因为两个陌生人之间是完全可能发生这种博弈的。它的问题在于,它假设社会有一个起点状态,在这种状态下,不熟悉的陌生人各自本来是孤独的,彼此之间是陌生的,好像是穴居的动物一样,在这种起点状态下,人和人开始交往并结成团体。卢梭的社会理论就是建立在这种起始状态之下的。

然而在我看来,这种状态并非人类社会的常态,毋宁说是一个非常态。人是群体生活的动物,绝大多数的人类都是在社群中长大的,人类社会的常态应该是聚众而居。当然这并不意味着我们应该抛弃猜疑,把信任当作是社会学理论的起点,人和人之间的交往是一个动态的过程,猜疑和信任都只是这个过程中的一部分。如果要我为社会学理论选择一个起点的话,我会选择人和人之间有猜疑的信任,或者说有误解的交流,而非绝对的猜疑。

对方可能会提出反对意见:宇宙中文明之间的遭遇,更多与穴居动物的遭遇类似,而与已经建立了信任关系的社群无关。所以即使猜疑链在人类社会中不合适,在宇宙中却是绝对合适的。

我的意见是,猜疑链这个概念用来描述人类社会过于高估了猜疑,而如果用在宇宙社会中,恐怕是高估了信任,准确地说是文明与文明之间的了解。

事实上猜疑链这个概念本身就已经包含了了解的成分,正是相信对方又与我类似的价值观和行为模式,所以才有“以己度人”的余地。因此,即使我觉得章北海率领的舰队之间的勾心斗角可以接受,我还是忍不住要怀疑,宇宙中的文明遭遇,会有这样的前提么?

假如A星球的文明与B星球遭遇,他们能马上了解彼此之间的实力差距么?假如对方有意掩藏起了自己的实力怎么办?假如对方的科技水平并非单纯反映在对外层空间的探索上怎么办?又或者,假如对方对于生命和宇宙有跟我完全不同的态度怎么办?率先攻击会不会反而招来飞来横祸?那是不是不攻击反而会是更为明智的选择呢?

最后一条:技术爆炸。

这一条没什么好驳的,因为在我看来是顺理成章地不成立。现代人被现代以来的人类历史框住了思维,总是以为近五百多年来的技术持续进步是顺理成章的,甚至以为加上人类所有历史的过去,就是一个理论不断上阶梯,技术突破瓶颈的历史。这是典型的进化论的宏伟叙事。

回首人类的历史,我们会发现许多古代的工艺至今难以复现,而很多技术,实际上经历了一个重复失落和再发明的过程。近几百年来的技术爆炸到底是个偶然还是必然,现在还无从知晓。再往深了质疑,连近几百年来的技术爆炸是否成立也成问题,因为随着现代性的演进,人类一边在不停地发明出新的技术,一边在不停地失去旧的技术。我们的社会从没有现在这样先进,也从没有现在这样单一。技术在未来到底是会不停地爆炸下去,还是会反过来将人类吞噬,现在是个谁也说不准的事情。因此断定技术爆炸是文明的一条支配法则,显然是过于短视了。

还要提宇宙的特殊性的话,我只能说,依据小说的内容,连三体文明都是技术匀速发展的,凭什么断定这个概念的合理性呢?

最后谈谈理论的取向问题。

在自然科学里面,我们常说“发现”了一条原理,包含的意思,是说客观规律是不以人的意志为转移的,只等着人类的意识去接近。而在社会科学里,尤其是八十年代以来,我们常说某人“发明”了一条原理,因为我们承认,社会科学的理论(或者更前卫一点说,我们认为人类所有的理论)都是“发明”出来的。是带着特殊用意的建构。《三体》中的宇宙社会学也是这样,用意无非是要营造出一种残酷的宇宙丛林法则来,好支撑小说情节的展开。

然而即使我承认这只是小说的笔法而已,我还是要挑剔一番,因为我实在不忍心看到这样一部充满了坚实的自然科学细节的幻想小说,在社会科学方面出现这样不成熟的设想。这与天马行空的前瞻性幻想不同,大刘的“宇宙社会学”再现出来的,其实只是社会学早在四五十年前就已经抛弃的一些陈腐思想,有些想法的渊源,甚至可以上溯到启蒙时代一些自然科学家和政治学家对于人类社会所做的臆测,以及从自己学科出发的轻率比附。尽管充满童趣,然而很遗憾,这些“人对人是狼”、“社会遵循数学模型”、“技术不断进步”之类的幻觉,在社会学里已经属于史前史了。

从理论根源上去追溯这种社会观是一条路径。让我更感兴趣的小说中具体的思想路径。叶文洁从自己文革的经历中得出这样的社会观,可以理解。我也可以理解经历过文革的一代人这样去认知社会。但是,与他们认为“文革把整个人类社会还原到了原点”,故此可以通过文革中的人际关系去认识社会不同,我认为文革状态是人类社会的一种极端形态,就此把“社会”定义成一场“无仁义的战争”,恐怕有失偏颇。

值得大力肯定的一点是,《三体》这部瑰丽的科幻小说第一次从正面肯定了社会学的价值。作为一名社会学从业者,我深深感谢大刘老师对于这门学科的推重,同时感佩于大刘老师的眼界之宽广。如果有说得不对的地方,欢迎讨论。

读完这本小说,我的心里多了一个幻想。我憧憬着,有一天我从梦中醒来,赫然发现两位黑衣人站在我的床头:“嘘……先生,对不起,请跟我们来一趟,外星事务司现在急需一名社会学学者的帮助。”

to 某些看官:鉴于这个文下面的海量回复,却营养偏低。各位的奇思妙想,恕在下不一一回复了。你们大可以当作已经打败了我,同时成为了宇宙社会学的第一代开山伟人,侍立在大刘老师左右护法。嗯嗯,我不介意,一点都不介意。只要别再跟贴骚扰我就行,因为豆瓣是关不掉回复提醒的。谢谢!:)

2009-07-05 07:08:21 Singkle

文理分科害死人啊,LZ的眼光太狭隘了,说来说去跳不出”人”这个概念,问题是宇宙中的其他文明”不是人”啊。。。简单的说,蚂蚁也有它们简单的社会,在蚂蚁的小社会中,一切LZ所学的人类社会学知识统统作废,如果人类社会和蚂蚁社会互动,该怎么去研究?

所谓”宇宙社会学”,就是基于比人和蚂蚁还要夸张的人和外星人的社会关系研究,不是简单的把”外星人”等同于外星的”人”就可以了。。。

。。。逐条批驳。。。不要介意。。。

1、生存是第一需要

LZ所说的,还是陷在”当代地球人”这个死胡同里出不来,”当代地球人”和地球上的其他生物最大的不同就是:大体上,不用为生存担心了。之后才有lz所说的“成瘾性”或是其他需求。生存依然是第一需要,如果谁质疑这一点,大可以把他扔到东非草原去,体验一下200万年前祖先的感觉。如果作为一个种族,都不把生存作为第一需要–人类社会确实出现过这样的文明–那么结局也只有一个:灭亡。

大刘在书中更是设计了一个极端条件下的文明:三体世界。在那里,明天太阳会不会升起来是不确定的,行星是可能被恒星吞噬的,睡下是可能永远不会醒的。在宇宙中和这样的文明竞争,不把生存放在第一位,只有死路一条。”文明本身是有重量的”?看看人类为了资源、土地曾经对自己的同胞做过什么吧。更不用说为了生存,我们毫不犹豫的灭绝了成千上万的物种,把大片大片的肥沃土地据为己有,强迫其他物种作为我们的奴隶和食物,LZ心安理得的说着“生存的第一需要也是可以被牺牲的”时候,却不知道为了今天我们的舒服日子,地球上已经有多少物种的生存被牺牲掉。

我不是要谴责谁,我只是想提醒一下LZ,在宇宙中,“生存”不是理所当然的事情。如果我们是两只非洲羚羊在交流生存的问题,你会更容易理解这一点。

2.文明扩张,资源总量不变

这个必然造成冲突嘛,LZ真的是学社会学的?地球上自不同文明开始接触之后,就是围绕着有限资源在不断的冲突、战争。一个又一个的文明因此而灭亡。典型的例子就是印第安人,基本上死光了,丧失了所有的土地和资源,如果美洲大陆的原住民不是印第安人而是印第安黑猩猩,那么毫无疑问的,这个种族就灭绝了。近代不过因为技术进步和核平衡,世界太平了50年。。。。大刘在这里一针见血,毫无幻想的直面现实:三体人垂涎地球舒适的环境,准备占领太阳系,禁止人类繁殖。即使是从人类历史也能推出这样的结论。

3、猜疑链

还是那句老话,文科生。。。哎,只能叹气,“了解”、“信任”、“猜疑”的绕了半天,一板砖拍死:你看见你脚边有只蚂蚁在爬,你会踩死它么?结论是,你完全不知道它在想什么,完完全全的不知道。这就是宇宙尺度的交流,为什么会这样?因为任何两个人的基因相似程度都在99。99%以上,但人和猩猩的基因相似度只有95%,5%的差异就导致人和猩猩无法交流(猩猩和猩猩之间显然是可以交流的),人和蚂蚁就更不用说了。

以上还只是在地球上的情况,宇宙间的情况更是千奇百怪,甚至可能不是碳基生命,甚至可能不是物质生命,如何确定对方的善意?

4、技术爆炸

技术爆炸确实是个不够严谨的名词,但是技术爆炸这种可能性给猜疑链上了锁。脚下的蚂蚁,你可以踩死或者放过,因为你知道蚂蚁再进化100万年也不会伤害到你。但是,如果存在这种可能性:只要50年时间,蚂蚁就可以进化出反物质炸弹(崩管用什么方法),人类会采取什么什么行动?毫无疑问的,地球上的蚂蚁,这个存在了几亿年的物种,只有49年好活了。。。有了技术爆炸这种可能性,猜疑链变得牢不可催。

在宇宙尺度上,星际旅行可能是已世纪为单位进行的,甚至更长,大刘的笔法当然夸张了一些,派几个质子来封锁地球科技,毕竟是小说细节不能太较真。

但,真是因为技术爆炸这种可能性的存在,猜疑链的两端才会从不信任转向忧虑以至于直接摧毁。这绝不是耸人听闻,古巴导弹危机就是很好的例子,苏联如果成功在古巴部署了导弹,就相当于技术爆炸(一夜之间获取了2分钟导弹攻击美国本土的能力),美国当时的态度就是不惜一战,哪怕核战也在所不惜,星际战争的毁灭程度更胜核战,如果潜在对手技术爆炸,人类面临的不仅仅是“核冬天”,而是太阳系的毁灭。。。

以上的几点其实大刘在书中已经把道理说透了,只是人类的习惯性思维总是把宇宙间的对手潜意识里定义为“另一种人”,殊不知“非人”的宇宙中,道理,是不那么好说的通的

2010-05-25 15:12:11 mihawk
举不出例子是我才疏学浅。逻辑上成立实际上也存在的事没什么稀奇的,听说证伪才比较有价值,您觉得呢?

至于什么博弈不博弈的,我懒得去想,也没那么高智能,只以低等智慧的直觉打心眼里反感高等文明还会被类似囚徒困境一类的傻逼博弈给难住,一点儿自信都没有。还有生命的意义在于生存?去他娘的。绝对的理性只会导致绝对的专制,而专制社会能发展出什么程度的智能??

我不管推演基于什么理论,如果前提是有问题的,推演的再激烈也是扯淡。从人类社会的发展来看,技术越发达,相反文明中个体的数目反而越少,因为技术让个体在时间上和空间上能够掌握的资源更多了,高素质人群中才有丁克一族吧,也没听说哪物理学教授以多生儿子为乐吧。这样推演至极致,文明的终极形式能占有整个宇宙的资源,可以与宇宙共存亡,这不就是宇宙本身吗?宇宙快把我们消灭吧,人类太矬了。再往低等一点的文明,利用宇宙一半的资源,能活个几十亿年,这种文明有可能有很多个体吗?没的话,他怎么扩张啊。他干嘛消灭其他文明啊……这就扯远了,总之黑暗森林理论的前提是很扯淡的。

2010-05-25 23:55:47 cloned
文明中个体的数目反而越少,因为技术让个体在时间上和空间上能够掌握的资源更多了
========================
生产力在发展的同时 生产资料的范围也在扩大 而并不是严格意义上的总量固定 所以抢占其他文明资源的逻辑关系至少不是严格成立的 譬如回到200年前 谁能想到核电站的出现?5000年前 农业里生物能是首要能源 牛啊骡啊什么 现在发达农业国家谁还用牛来耕地?所以文明的终极形式 我认为只是“有能力”占有 但是它却“不需要”占有

高素质人群中才有丁克一族吧,也没听说哪物理学教授以多生儿子为乐吧
====================================
丁克一族的出现 是因为个体掌握的资源多了 这个逻辑关系如何成立?我倒偏向认为是社会价值观的改变 生孩子的机会成本太高 物理学教授不以多生儿子为乐 是因为政策决定只能生一个 如何多生?国外的教授一家谁没好几个小孩?至少教我的教授是这样

2010-05-26 08:35:20 mihawk
说的不错,我这里有些表述不清的地方。我同意你说的生产资料范围扩大和“有能力”占有啊,我说的就是“能够”啊。但你得看是以什么形式扩大的,你举的例子都是能源使用上的扩大,这方面的攫取确实是没有止境的,我理解的高等文明应当可以一劳永逸的解决这个问题,比如可控核聚变甚至更高级的形式,我不信哪个文明要把整个宇宙的质量都转换成能量供自己发展,所以这方面文明间可以不存在矛盾。除此之外人类最大的消耗是什么呢?我认为是基本生存要素,吃啊穿啊什么的,这点不同类型文明间应当是我说的没有矛盾的。
当然不是因为掌握资源多了就直接导致丁克一族,但两者之间不是没有关系的,就像你说的生孩子成本太高,为什么呢?还不是因为资源掌握导致其他方面的效用提高,相比较而言生孩子成本高了。有好几个孩子也不等于以生孩子为乐啊,那些教授能跟一些印度人一样,穷的要死还猛生,只为了多几个劳动力?如果每个人能够动用的资源都很大,你觉得现在的地球还能有几个人?早就打的不可开交,然后剩下极少的均衡的个体了吧。
总之这个理论越想越操蛋,不想了,等外星人来指教吧。

2010-05-26 17:43:47 zzzwalker
“打心眼里反感高等文明还会被类似囚徒困境一类的傻逼博弈给难住,一点儿自信都没有”不幸的是至少在《黑暗森林》里不管多高等的文明都会被一些光速极限(用量子效应打了擦边球,第三部的转机可能就在于此)、能量守恒、熵等“地球傻逼文明”发现的定律难住,在这些面前自信什么就是废话。就算上帝都得被“能否创造自己举不起的石头”这类傻逼问题难住。
还有,你弄混了技术发展与文明高等——虽然在《黑暗森林》里对于高等文明没有定义。你所举的不追求生存的艺术化文明也许有,但是在剧烈生存竞争中它们被追求生存花文明灭掉的危险性也会使它们在进化上呈减少趋势。
另外,你还得考虑技术进化中的不平衡趋势,不同文明间的即时通讯在《黑暗森林》中是无可逾越的天堑,而远距离彻底毁灭一个文明即时以地球的傻逼文明技术手段也是有可能的。
至少在我看来,《黑暗森林》里的理论是可以自洽的。对于小说来说已是足够了。

2010-05-27 13:16:02 风间隼
中国社会学就是被你说的那种“严谨科学观”带到泥坑里去的,活人构成的意义世界是能用数学表达出来的么?那种向自然科学看齐的社会学观充其量只是社会学中的一种研究取向而已,有他的优势,可绝对称不上标杆或者指路牌那样的地位。倒是那种异常骄矜的态度,有负“科学”之实。

我是缺乏理科眼界,我本来就不是学那个的啊。社会学的分支多了,生物学、心理学、经济学等学科,什么系统论、信息论、博弈论等理论都觉得自己有资格成为社会学的学科基础,也都抢到了或抢到过一份地盘。依我看,他们都有用,可要说“成为基础”,他们都需要多了解一点社会的基本性质再说话。

2010-06-29 00:03:49 嘻歪呦
我本科是社会学的,不想来搅这趟浑水了,我只想说,社会学作为一个学科,亏就亏在它要在谁都有能力和意愿发言的地方建立起一种规范,这就很难去向别人解释它如何成为科学,因为到最后,这个规范无非还是由权力和意志来决定,不像自然科学,要么懂,要么不懂,不懂的就不会发言,门槛在那里。懂了就放之四海而皆准,至少在限定的范围内不会出错。
但是社会科学既然是科学,它就只管“实然”,而不管“应然”,所以一个社会学理论要面对的首要问题就是它是不是“实然”的,如果不是的话就根本构不成科学,所以我很赞同LZ的分析思路。
但是往下就不好说了,因为小说里的东西没有办法去实证,面对一个不能证明或者证伪的东西我想最好还是保持沉默。LZ提出这些问题是从社会学的角度去考虑,但是读者普遍只从社会的角度考虑,一字之差,谬以千里。

2010-06-29 09:29:49 Mega
其实我现在觉得LZ有的话还是对的,那就是大刘确实不应该用“社会学”这几个字,毕竟是牛头不对马嘴。文明之间的关系更象是国际关系学而不是社会学,也许叫“星际关系学”更恰当。罗辑最后解决危机的办法也还是人类国际关系中的势力均衡原则而已,只不过原子弹变成了来自未知文明的威胁。
不过名字不对并不说明大刘的命题不能自洽,只是大刘在取名时的一个失误罢了,他毕竟不是学社会科学的。但如果一定要站在他取错名字的角度去批判他的理论,就好比哺乳动物学家去研究海马,只是因为它的名字里有“马”一样。

固态硬盘写入性能与空闲空间的关系

写这篇文章时我还没有购买过一个固态硬盘,但却还是想写些东西,因为最近用过多个 U 盘这样的闪存设备,所以有感而发。诚然,固态硬盘是相当于多个闪存芯片进行类似于 RAID0 磁盘阵列的构造,因此性能比 U 盘要快上太多,但是由于它仍是闪存芯片,所以闪存芯片的性能局限还是会影响到它。

首先,对 SSD 的写入与 U 盘不同的地方作个简介:闪存写入时都是以“块”为单位的。每个块根据闪存型号的不同而有所不同,但通常是 512KB 到 2MB 之间。写入一块内容时,要考虑此块是否有有效数据,以及是否已擦除。如果有有效数据,必须先复制出来,然后擦除,然后将老数据与新数据合并,如果能在块中容纳则全部写入,否则写入能容纳的部分,不能容纳的部分将与后一块的数据进行合并。由于在写入前会确认总空间是足够的,因此总有一个块中有足够的空闲空间。这个空闲与占用的空间是以“页”为单位标记的,一个块中有多个页。

由上述描述可见,有时候写入的数据不到一个块的大小,但实际发生的写入可能涉及多个块。这个效应叫“写放大”。为了减少这个效应,一则 SSD 需要区分空闲与不空闲的空间。这个在 Windows 7 和 Linux 2.6.33 内核中终于有了支持,使用的叫 TRIM 指令。二是 SSD 需要把含有部分数据的块集中到一起,这样让空闲的块都能是整块整块空闲的。这个工作叫做“垃圾回收”。

如果有 10 个块,每个块都有 80% 的数据,那么对它们进行垃圾回收需要写入几个块呢?答案当然是 8 个块。另一方面,如果 10 个块,前 8 个块有 100% 的数据,后 2 个块全空,那垃圾回收需要写入几个块呢?一个都不需要,因为空闲空间已经集中在一起了。可见,数据越连续(比如之前已经做过垃圾回收了,或者写入时都是大段大段写入的,每段数据都比一个块大许多),那么垃圾回收的速度就越快。否则就越慢。另一方面,如果是 10 个块,每个块都有 50% 的数据,那么垃圾回收需要写入几个块呢?5 个块。比 8 个块好些。

一般 SSD 会预留 7%~40% 不等(具体看厂商)的空间用于垃圾回收(这些空间是 SSD 标称容量之外的)。在系统运行时,后台也会默默地自动进行垃圾回收。总之,SSD 的性能方面和硬盘一样,会有一定的随机性。垃圾回收也像硬盘上的磁盘碎片整理一样,对提高性能有帮助。现在看来,SSD 使用时也不用过多担心空间问题,只是要了解到垃圾回收是需要时间的,在写入 10GB 数据的时候,可能有着 20GB 数据需要垃圾回收(比方刚刚删了好多小文件,影响到了 20GB 的块),就不会在写入慢的时候错怪我们的小固盘了。

参考资料:

http://article.pchome.net/content-1415517-11.html
http://bbs.pceva.com.cn/thread-9314-1-1.html
http://en.wikipedia.org/wiki/Write_amplification

The case of the crashing mplayerc

2012-04-28
Decheng (Robbie) Fan

Today I found on my computer my mplayerc crashes when playing an MOV file. I thought there might be something wrong in its settings. The current environment looks like below:

Installed componnents:
Ringz Studio Storm Codec (containing mplayerc and ffdshow)
ffdshow
FormatFactory

I uninstalled ffdshow, Storm Codec and reinstalled them. mplayerc still crashes. It even crashes when playing an OGG file.

I found it doesn’t crash when running under an administrator account (I’m running as normal user).

Later I used Mark Russinovich’s procmon to trace the crash process. I guess there is something wrong in its configuration. I found registry keys under HKCU. They’re GNU and Gabest. The GNU key contains ffdshow settings. I deleted the key. mplayerc still crashes. I deleted Gabest key. It still crashes. By searching through the procmon trace, I found another one under HKCU\Software\Classes\VirtualStore. This is the virtualization by Windows Vista to store data for applications that writes to system settings when running under normal user. I found there is also a Gabest setting. Under it there was a key pointing to a ffdshow dll directory that is used by FormatFactory. Oh, that’s why. I deleted the key and it works!

Another issue solved with the help from the utilities from Sysinternals and Mark Russinovich!

从 Effective C++ 中讲到的虚析构函数想开去

已经有两年主要用高级语言,如 ABAP、Python、Java 等编写程序了。对 C/C++ 程序看上去还是很熟悉,特别是纯 C 程序和只用类和继承而不用多少模版的 C++ 程序。最近又在重温 Effective C++。对于这本书我大学时候也没有从头到底看过,但是觉得它讲的很多东西非常有道理,所以就把它列作必读书目之一。这次从头重新看起,然后就看到了现在讲的条款 14,要求基类有虚析构函数的这一条。

看到这一条时,首先想到的是未定义行为。C++ 对于基类没有虚析构函数的情况,当一个指针指向其子类对象后 delete 此指针时,行为是未定义的。“未定义行为”是什么概念呢?书中说得比较有趣:可能会格式化你的磁盘,可能给你的老板发送邮件,可能把你的程序代码传真给对手,。。。当然实际上这些事情发生的概率如同让猴子在键盘上打出几个有意义的英文单词的概率差不多。但不管怎样,C/C++ 中的未定义行为总是让人比较担心的。有时,一个因数据不一致或堆内存破坏而引起的 bug,其根本原因往往是一段时间以前不小心执行的一个未定义操作,例如两次 delete 指向同一个地址的指针,读写了已经被释放的内存块,指针或数据没有被初始化,使用引用来指向栈上的一个临时变量,运行了多次析构函数,向一块内存写入超过它容量的数据等等。正因为这个原因,在 C/C++ 中对于异常的处理就非常重要,但是由于语言支持的关系,C 语言中对异常处理基本没有语言支持,C++ 中虽然有异常和栈开解等机制,功能上完整了,但却用了个“没有强制公共基类”以及“没有堆栈跟踪”的设计,导致实际调试异常成了非常艰巨的任务,非得有可重现的步骤以及用“人工二分查找”,对于类库抛的异常还得有文档,这三个条件同时满足才行。因此实际使用此机制的程序很少。i386 保护模式和一些外部工具如 AppVerifier 和 Valgrind 等能够检测一部分问题,配合 checked build 等方法,的确能消除很多 bug,这才相对有所放心。

然后想到的是基类和子类的构造和析构问题。每次构造一个子类对象,其基类的构造函数会先被调用,然后再调用子类的构造函数。每次析构一个子类对象,其子类的析构函数会先被调用,然后再调用基类的析构函数。这在析构函数为虚函数的情况下成立。那么析构函数为什么要被声明为虚函数,而不是直接默认为虚函数呢?C++ 这方面的考虑肯定是出于性能。虚函数调用时需要通过对象的 vptr 指到 vtbl,再从 vtbl 中指到一个固定偏移的函数指针,然后调用此函数。类似于 call this->vptr[offset] 这种概念,因此会比较耗时。那么虚析构函数执行的过程,很可能是调用对象实际所在类的析构函数,然后该子类析构函数的尾部会调用上一层基类的析构函数,上一层基类析构函数的尾部再调用更上一层,以此类推。也就是说,我们在 ~SubClass() {…} 这样的函数中看到的代码之后实际还隐含了一个调用 SuperClass::~SuperClass();,除非是最根本的那个基类。

最后想到的是两年前看过的文章 Ian Joyner: a critique of c++ and programming and language trends of the 1990s。里面说到 Java 的方法默认都是虚函数(除非 final)。C++ 的虚函数则要显式声明,这样的话,如果一个类的某个函数没有显式声明为虚函数,那么将来如果要在子类中用同名的函数重写这个函数的话,就必须修改基类代码,这在一个类库中是很不合适的事情,特别是那个类库的源代码无法被应用者修改的情况下。此处我想,最好的解决方法自然是修改源代码,如果可能的话。如果不行,并且找类库主人不方便,则应考虑使用组合代替继承,然后在组合的类中再使用函数指针等方法显式解决此问题。如果还不行,比如有其他类直接使用此基类指针,在此情况下还需要有虚拟特性的,那就只有找类库主人了,这个没什么话好说,谁让他是主人呢。人家用 C++ 的目的和 Java 本来就不一样,所以不应该用对 Java 的要求去要求 C++。但是异常处理除外,异常本来就不是一个小开销的东西,而且是一个调试利器,应该索性做得好些。

ReadyBoost–Robbie 的基准测试

2012-04-14
Robbie Fan 范德成

背景:我以前对 Windows Vista ReadyBoost 并没有多少信心。我曾认为它没有达到我的期望,因为我粗略的性能对比测试显示在跑了一个内存消耗程序把其他进程的工作集清出内存之后,ReadyBoost 并没有出现明显的效用。然而,这回我对它的理解改进了,认为它虽然看上去没有 Windows 7 的 ReadyBoost 那么好,但它仍有它的效用。

配置:笔记本电脑,内置 120GB 的(每分钟)5400 转硬盘,连续读取性能 50MB 每秒。Intel 酷睿 2 双核 CPU 运行于 800MHz(省电模式)。3GB 内存。4GB 的 ReadyBoost 缓存设置于一只金士顿 16GB U 盘,其连续读性能为 20MB 每秒,连续写性能为 7MB 每秒。

基准测试方法:我使用两个各消耗 1GB 内存的程序。每个程序本质上分配 1GB 内存,读写每一个内存页,然后释放掉这些内存。它们在一开始被设为反复启动。当运行了一定次数后(20~30 次),我关闭这些内存消耗程序并开始记秒数。等到磁盘活动恢复正常(资源监视器中平均磁盘时间小于等于 30%,或任务管理器中缓存大于等于 300MB)后停止记时。

结果:

  • 不用 ReadyBoost:155 秒
  • ReadyBoost 开启但没有很多预填充:119 秒
  • ReadyBoost 开启并有足够的预填充:35 秒

资源监视器,通过它可以看到内存消耗程序的行为

解释一下:Windows 实现了一种叫进程工作集的概念。一个进程有 4GB(或 x64 上是 16TB)虚拟地址空间,其中一部分被映射为 4KB 大小的内存页。Windows 不断跟踪最近被使用的页面和最近较少使用的页面,并试图把尽可能多的页面留在物理内存里。最近较少使用的页面被换出到硬盘上。注意虚拟地址空间可能包含匿名内存(比如 C 语言程序中的全局变量和用 malloc 函数分配的内存),它用页面文件来作备用存储,还可能包含内存映射文件(包括可执行文件的正文)。只要一个页面自上次被加载到物理内存后已被修改过(或者它是一块新分配的内存,之前从没在磁盘上存在过),一个换出操作将包含向页面文件或内存映射文件写入的操作;其他情况下它不做任何事情。

当进程访问一个在物理内存中不存在的页面时,Windows 必须做一次换入操作。因为之前换出的页面是基于使用情况的,它们很有可能分散在地址空间的各个位置(当考虑到动态内存分配时尤其如此)。另一个相对次要的问题是有时候页面文件中的空闲空间不是连续的。由于前述两个问题,换入可能带有许多非常随机的读操作。这样一来我们就遇到了一个当代硬盘的性能瓶颈:寻道时间 + 旋转时间。每个随机读操作都需要一次磁盘寻道和旋转,对硬盘来说这个时间是约 10~20 毫秒。即使是每分钟 7200 转的硬盘,时间还是超过 5 毫秒。Windows 可以通过预读页面文件中连续的几个页面来优化换入操作。假定在最坏情况下,每个换入的预读操作都没有命中,并假设 10 毫秒读一次,那么每秒将有 400KB 的内存换入。通常情况比这好些,但是据我从资源监视器中观察的结果来看,平均速度还是在每秒 2MB 以下。

性能监视器监视 ReadyBoost,显示出未很好地填充时的状态

相反,使用闪存存储器工艺的 U 盘有着高得多的随机读性能,大约每次 1 毫秒(虽然比物理内存还是慢得多)。因此我们可以期望用它来加速换入操作。然而,它无法给换出操作明显加速,因为它的顺序写速度仅为 5~10MB 每秒。由于它可移除,而且不同品牌和型号的产品质量也有高低,它并不是页面文件的理想替代品。因此 ReadyBoost 把它用作性能加速器,但却不是页面文件的存储器。

Windows Vista 的闪存设备利用方案包含两个部分:Superfetch 和 ReadyBoost。ReadyBoost 缓存的填充有两个途径:由 Superfetch 填充,或保存换出页面和写入磁盘的内容。Superfetch 填充是 ReadyBoost 缓存的主要组成部分。Superfetch 是一个“预测”将来会用到的页面的技术。作为微软研究院(Microsoft Research)的理论研究转化出来的产品,它使用人工智能来分析页面的访问形式,从而按页面可能被访问的概率排序把页面保存在物理内存中或闪存中。将来最可能被访问的页面放在物理内存中,而被访问的可能性低些的页面放在闪存中。

你也许知道,闪存设备的随机写性能比较低。这是因为每次一个地址要被写入时,整个闪存块(有些情况下大至 2MB)需要被读一次(并备份),擦除再被写入。ReadyBoost 为了高效地写入闪存,它必须尽可能缓冲并序列化写入。由于记录的页面相当随机,从设备的读取也将很随机,但这正是闪存的优势所在,故不存在问题。ReadyBoost 在闪存设备被插入时会预先测试它,只要它的 4KB 随机读性能超过 2.5MB 每秒并且 512KB 随机写性能超过 1.75MB 每秒,就认为它是可用于加速的。ReadyBoost 使用数据压缩来更有效地利用缓存空间。

性能监视器监视 ReadyBoost,显示出已很好地填充后的状态

我的性能测试显示 ReadyBoost 缓存在反复运行内存消耗程序的情况下能被很好地填充。“很好地填充”的定义是:经常使用的页面在缓存中。我对测试结果的解释如下:第一次启动内存消耗程序时,假设有 1.4GB 工作集在物理内存中,那么其余的 1.6GB 物理内存将包含相对较少可能被访问的页面。ReadyBoost 缓存将被填充进比那 1.6GB 物理内存中的页面更少可能被访问的页面。所以,如果我的内存消耗程序把 1.6GB 缓存和 0.4GB 工作集清出物理内存,ReadyBoost 也不太可能在这些页面被换入时帮上什么大忙。

然而,当内存消耗程序反复启动后,将发生两件事情。第一,Superfetch 将随机地遇到内存消耗程序占据了物理内存,而 Superfetch 无法把页面填充到其中的情况。第二,0.4GB 的工作集将周期性地被清出物理内存,从而 Superfetch 将试图把它们取回到缓存中。这样一来,这 0.4GB 就有一定概率被保存到 ReadyBoost 缓存中。从而,在 Superfetch 填充了足够长的一阵子之后,它们很有可能就在 ReadyBoost 的缓存中,并能被快速地加载回来,而不是慢吞吞地从硬盘上读取。这是对我的测试结果的一个解释。

在我使用了 ReadyBoost 足够长的一段时间,并观察了它的性能图形(命中读取字节/秒 和 顺序 IO 放弃/秒)之后,我想说一个小现象:ReadyBoost,或严格地说是 Superfetch,不会预取“数据映射表”,就是说文件系统结构(MFT(主文件表),目录(文件名)等等)。这些数据仅由缓存管理器在物理内存中进行缓存。

作为对本文的总结,我对如何利用好 ReadyBoost 的建议:当物理内存紧张时,可能的话多买点内存条并插上。然后拿一个快速的 U 盘来使用 ReadyBoost(直接插电脑 USB 口,不要用延长线或集线器)。避免把各种各样的数据同时塞进内存。当你的笔记本电脑使用电池供电时,启用 ReadyBoost——它会帮你节省电量。如果你的电脑有一个固态硬盘(SSD),就不要用 ReadyBoost 和 Superfetch 了。

ReadyBoost–Robbie’s Benchmark

2012-04-14
Decheng (Robbie) Fan

Background: I was not confident about Windows Vista ReadyBoost. I always thought it didn’t meet my expectation, because my rough benchmark showed that it is quite ineffective after using a memory hog program to clear out processes’ working sets. However, this time I understood better about it and I think although it didn’t seem to be as good as Windows 7 ReadyBoost, it still has its effect.

Configuration: A laptop computer, with a 120GB 5400RPM hard disk drive, which has 50MB/s sequential read speed. Intel Core 2 Duo CPU at 800MHz (power-saving mode). 3GB RAM. 4GB ReadyBoost cache on a Kingston 16GB USB thumb drive, which has 20MB/s sequential read speed and 7MB/s sequential write speed.

Benchmark method: I use 2x1GB memory hog processes. Each memory hog program essentially allocates 1GB memory, touches every page in it, and deallocates the memory. They are first set to repeated launch. After several times (20~30) of repetition, I close the memory hogs and begin recording the time. Then wait until disk activity becomes normal (average disk time <= 30% as seen in Resource Monitor or cached >= 300MB as seen in Task Manager) and stop recording time.

Result:

  • Without ReadyBoost: 155s
  • ReadyBoost without much pre-population: 119s
  • ReadyBoost with enough pre-population: 35s

Resource Monitor, through which the memory hog behavior can be seen

Explanation: Windows implements the concept of process working sets. A process has its 4GB (or 16TB on x64) virtual address space partially mapped as 4KB memory pages. Windows keeps tracking pages that are recently in use and that are less recently in use and tries to keep as much recently-used pages in RAM as possible. Less-recently used pages are paged out to the hard disk drive.  Note that the virtual address space may contain anonymous memory (such as global variables in a C program and memory allocated by “malloc”), which is backed by the paging file, and portions of memory-mapped file (including executable file text). As long as a page is modified since last time it is loaded into the RAM (or if it is a newly-allocated piece of memory that never existed on the disk), a page-out would involve writing to the page file or to the memory-mapped file; otherwise it is a no-op.

Whenever a process accesses a page that is not in the RAM, a page-in operation is required. Because pages previously paged out are based on usage pattern, they are probably scattered around the address space (especially considering dynamic memory allocation). A minor issue is that sometimes the free space inside the paging file is not contiguous. Due to the two issues, paging in may involve many, quite random, reads. Now we come to a performance bottleneck of the contemporary hard disk drive: seek time + rotation time. Every random read requires a disk seek and rotation, and it is about 10~20ms (milliseconds) on a hard disk drive. Even with a 7200RPM drive, it is still above 5ms. Windows can optimize page-in of contiguous pages by reading ahead (in the page file) several pages at a time.  Suppose in the worst case, every page-in read-ahead doesn’t make any hit, with 10ms per read, it would be 400KB per second. Usually it is better, but from what I see in Resource Monitor, the average speed is below 2MB per second.

Performance Monitor for ReadyBoost, showing not populated enough behavior

On the other hand, the USB thumb drive, being made of flash memory, has much faster random read rate, at about 1ms per read (although still much slower than RAM). So we can hopefully use it to accelerate page-ins. However, it cannot accelerate page-outs very much, because its sequential write speed is just about 5~10MB/s. Since it’s removable, and the quality varies between different brands and models, it’s not an ideal replacement for the paging file. So ReadyBoost uses it as a speed booster, but not as a place for the paging file.

Windows Vista’s approach to utilizing the flash memory device comes with two parts, Superfetch and ReadyBoost. There are two ways the ReadyBoost cache is filled: populated by Superfetch, or storing page-outs and disk writes.  Superfetch population consists of the major part of data in the ReadyBoost cache. Superfetch is a technology that “predicts” pages that will be used in the future. As an implementation of a theory from Microsoft Research, it applies AI in access pattern analysis, having a result of keeping pages in RAM or in flash memory sorted by the likelihood of access to them in the future.  Pages that are more likely to be accessed in the future are put in RAM, while those that are less likely to be accessed are put in flash memory.

As you might know, flash memory devices have a low speed for random writes.  This is because every time an address is written to, the whole flash block (sometimes as large as 2MB) need to be read (backed up), wiped and written. In order for ReadyBoost to write to the flash memory device efficiently, it has to buffer and serialize the write as much as possible. As the pages being recorded are quite random, the read from the device would also be random, but this is exactly where the strength of flash memory lies, so it is not a real problem.  ReadyBoost pre-tests the flash memory device as soon as it gets plugged in, and if the 4KB random read speed is above 2.5MB/s and the 512KB random write speed is above 1.75MB/s, it is regarded as suitable for acceleration. ReadyBoost uses compression in order to further utilize the space in the cache.

Performance Monitor for ReadyBoost, showing populated enough behavior

My benchmark showed how ReadyBoost cache can be well-populated in case of repeated memory hog programs. The definition of well-populated is: frequently-used pages are in the cache. My explanation to the benchmark result is that: upon first launch without memory hog, suppose there are 1.4GB working sets in RAM, the other 1.6GB of RAM will contain pages less likely to be accessed. The ReadyBoost cache will be populated with pages that are less likely to be accessed than those in the 1.6GB RAM. So, if my memory hog program drives the 1.6GB cache and 0.4GB working sets out of RAM, ReadyBoost is unlikely to help when these pages are getting paged in.

However, when memory hog programs repeatedly launch, two things happen.  Firstly, Superfetch will randomly meet situations that pages cannot be prefetched into RAM, when memory hogs dominate the space. Secondly, periodically the 0.4GB previous working set pages will be out of RAM, so Superfetch will try to prefetch them. Then, the 0.4GB has a certain chance to be stored into ReadyBoost cache. Thus, after enough Superfetch prefetching, they are quite likely in the ReadyBoost cache and can be quickly loaded from it, rather than be slowly read from the hard disk drive. This is an explanation to my benchmark result.

After my prolonged use of ReadyBoost and looking at its performance graph (Hit read bytes/sec and Sequential IOs bailed/sec), a small thing to mention is that ReadyBoost, or strictly speaking, Superfetch, doesn’t prefetch “data maps”, that is, file system structures (MFT, directories (file names), etc.). Such data is only cached in RAM by the Cache Manager.

As a conclusion, my suggestion on how to use ReadyBoost well: when RAM becomes tight, buy more RAM sticks and plug into your machine if possible, and then apply ReadyBoost with a fast USB thumb drive (directly plug in to a USB port rather than to use a connection wire or hub). Try not to put too much different kinds of data into RAM. Use ReadyBoost when your laptop is on battery power, and it will save you energy.  If your computer has a Solid State Drive, forget about ReadyBoost and Superfetch.