用于编译的RAM驱动器 - 有这样的事吗?

时间:2008-12-09 21:11:43

标签: caching compilation directory ramdrive

An answer (见下文)对Stack Overflow上的一个问题给了我一个很棒的小软件的想法对任何地方的编码人员都非常宝贵。

我正在想象RAM驱动器软件,但有一个关键的区别 - 它会镜像我硬盘上的真实文件夹。更具体地说 - 包含我正在处理的项目的文件夹。这样,任何构建几乎都是瞬时的(或者至少快几个数量级)。 RAM驱动器将仅使用空闲资源将其内容与后台硬盘驱动器同步。

快速谷歌搜索没有透露任何信息,但也许我只是不知道如何使用谷歌。也许有人知道这样的软件?最好免费,但合理的费用也可以。

已添加:我建议使用一些解决方案。他们将(没有特别的顺序):

  • 购买更快的硬盘驱动器(SSD或者10K RPM)。我不想要硬件解决方案。不仅软件有可能更便宜(免费软件,任何人?),但它也可以用于硬件修改不受欢迎的环境,例如,在办公室。
  • 让OS / HDD进行缓存 - 它更了解如何使用您的空闲RAM。 OS / HDD具有通用缓存算法,可以缓存所有内容并尝试预测哪些数据最需要未来。他们不知道对我来说优先级是我的项目文件夹。而且我们都知道得很清楚 - 无论如何他们并没有真正地缓存它。 ;)
  • 周围有很多RAM驱动器;使用其中之一。抱歉,这将是鲁莽的。只要有一点空闲时间,我就需要将数据同步回硬盘。在电力故障的情况下,我可以承受失去最后五分钟的工作,但不是因为我上次入住以来的一切。

已添加2:出现了一个想法 - 使用普通的RAM驱动器和背景文件夹同步器(但我的意思是背景)。有没有这样的事情?

已添加3:有趣。我刚刚尝试了一个简单的RAM驱动器。重建时间从大约14秒下降到大约7秒(不差),但增量构建仍然在~5秒 - 就像在HDD上一样。有什么想法吗?它使用aspnet_compileraspnet_merge。也许他们在其他地方用其他临时文件做某事?

已添加4:哦,很好的新答案! :)好的,我为你所有的反对者提供了更多的信息。 :)

这个想法的主要原因之一不是上述软件(14秒构建时间),而是另一个我当时无法访问的软件。这个其他应用程序有100 MB的代码库,其完整版本大约需要5分钟。啊,是的,它在Delphi 5,所以编译器不太先进。 :)将源放在RAM驱动器上导致了巨大的差异。我想,我得到它一分钟以下。我没有测量过。所以对于所有那些说操作系统可以更好地缓存内容的人 - 我会乞求不同。

相关问题:

  

RAM disk for speed up IDE

请注意第一个链接: 它链接的问题已被删除,因为它是重复的。它问道:

  

你的代码编译时你做了什么?

我链接的Dmitri Nesteruk的答案是:

  

我几乎立即编译。部分原因是我的项目很小,部分原因是因为使用了RAM磁盘。

18 个答案:

答案 0 :(得分:17)

在Linux中(您从未提及您所使用的操作系统,因此可能相关)您可以从RAM创建块设备并像其他任何块设备(即HDD)一样安装它们)。

然后,您可以创建在启动/关闭时以及定期复制到该驱动器的脚本。

例如,您可以进行设置,以便~/code~/code-real。您的RAM块在启动时安装在~/code,然后复制~/code-real(位于您的标准硬盘驱动器上)的所有内容。在关机时,所有内容都会被复制(rsync'd会更快)从~/code返回到~/code-real。您可能也希望该脚本定期运行,因此在发生电源故障等情况下您不会失去太多工作。

我不再这样做了(我在9.5 beta测试速度很慢的情况下将其用于Opera,不再需要了。)

Here is how to create a RAM disk in Linux.

答案 1 :(得分:15)

我很惊讶有多少人认为操作系统在确定缓存需求方面可以比在这种专门案例中做得更好。虽然我没有这样做进行编译,但我确实为类似的进程做了这些工作,最后我使用了一个带有自动同步脚本的RAM磁盘。

在这种情况下,我想我会使用现代的源控制系统。在每次编译时,它都会自动检查源代码(如果需要,沿着实验分支),这样每次编译都会导致数据被保存起来。

要开始开发,请启动RAM磁盘并拉出当前基准线。进行编辑,编译,编辑,编译等 - 一直为您保存编辑。

在开心时进行最后检查,您甚至不必涉及常规硬盘驱动器。

但是有一些背景同步器可以自动完成任务 - 问题是它们也不会针对编程进行优化,并且可能需要偶尔进行完整的目录和文件扫描以捕获更改。源代码控制系统正是为此目的而设计的,因此即使它存在于您的构建设置中,它也可能会降低开销。

请记住,在停电的情况下,后台同步任务未定义。如果出现问题,您最终必须弄清楚保存了什么以及未保存的内容。使用定义的保存点(在每次编译时,或在手动强制执行时),您会非常清楚它至少处于您认为可以编译它的状态。使用VCS,您可以轻松地将其与之前的代码进行比较,看看您已经应用了哪些更改。

答案 2 :(得分:4)

请参阅 Speeding up emerge with tmpfs Gentoo Linux wiki)。

使用Gentoo下的RAM驱动器加速编译是许多人以前编写的操作方法的主题。它提供了已完成工作的具体示例。要点是所有源和构建中间文件都被重定向到RAM磁盘进行编译,而最终的二进制文件被定向到硬盘驱动器进行安装。

此外,我建议您在硬盘驱动器上维护源代码,但git push您的最新源更改为驻留在RAM磁盘上的克隆存储库。编译克隆。使用您喜欢的脚本复制创建的二进制文件。

我希望有所帮助。

答案 3 :(得分:3)

我们过去几年前做过4GL宏编译器;如果将宏库和支持库以及代码放在RAM磁盘上,编译应用程序(在80286上)将从20分钟到30秒。

答案 4 :(得分:3)

使用https://wiki.archlinux.org/index.php/Ramdisk制作RAM磁盘。

然后我编写了这些脚本来将目录移入和移出RAM磁盘。在进入RAM磁盘之前,在tar文件中进行备份。这样做的好处是路径保持不变,因此所有配置文件都不需要更改。完成后,使用uramdir重新启动磁盘。

编辑:添加了C代码,该代码将运行在后台间隔给出的任何命令。如果有任何更改,我将tar--update一起发送以更新存档。

我相信这种通用解决方案能够为非常简单的事物提供独特的解决方案。 KISS

确保将路径更改为rdbackupd

ramdir

#!/bin/bash

# May need some error checking for bad input.

# Convert relative path to absolute
# /bin/pwd gets real path without symbolic link on my system and pwd
# keeps symbolic link. You may need to change it to suit your needs.
somedir=`cd $1; /bin/pwd`;
somedirparent=`dirname $somedir`

# Backup directory
/bin/tar cf $somedir.tar $somedir

# Copy, tried move like https://wiki.archlinux.org/index.php/Ramdisk
# suggests, but I got an error.
mkdir -p /mnt/ramdisk$somedir
/bin/cp -r  $somedir /mnt/ramdisk$somedirparent

# Remove  directory
/bin/rm -r $somedir

# Create symbolic link. It needs to be in parent of given folder.
/bin/ln -s /mnt/ramdisk$somedir $somedirparent

#Run updater
~/bin/rdbackupd "/bin/tar -uf $somedir.tar $somedir" &

uramdir

#!/bin/bash

#Convert relative path to absolute
#somepath would probably make more sense
# pwd and not /bin/pwd so we get a symbolic path.
somedir=`cd $1; pwd`;

# Remove symbolic link
rm $somedir

# Copy dir back
/bin/cp -r /mnt/ramdisk$somedir $somedir

# Remove from ramdisk
/bin/rm -r /mnt/ramdisk$somedir

# Stop
killall rdbackupd

rdbackupd.cpp

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>

struct itimerval it;
char* command;

void update_archive(int sig)
{
    system(command);
}

int main(int argc, char**argv)
{
    it.it_value.tv_sec     = 1;   // Start right now
    it.it_value.tv_usec    = 0;
    it.it_interval.tv_sec  = 60;  // Run every 60 seconds
    it.it_interval.tv_usec = 0;

    if (argc < 2)
    {
        printf("rdbackupd: Need command to run\n");
        return 1;
    }
    command = argv[1];

    signal(SIGALRM, update_archive);
    setitimer(ITIMER_REAL, &it, NULL); // Start

    while(true);

    return 0;
}

答案 5 :(得分:3)

我没有您正在寻找的内容,但我现在正在使用RamdiskDRAM ramdisk的组合。由于这是Windows,我对核心内存有3 GB的限制,这意味着我不能为RAM磁盘使用太多内存。 9010上额外增加4 GB真的很棒。我让我的IDE将所有临时内容存储在固态RAM磁盘和Maven存储库中。 DRAM RAM盘具有闪存卡的备用电池。这听起来像一个广告,但它确实是一个很好的设置。

DRAM磁盘有两个SATA-300端口,在大多数测试中平均寻找0.0毫秒;)圣诞袜的东西?

答案 6 :(得分:3)

您的操作系统会在内存中缓存内容。 RAM磁盘可能看起来更快,但这是因为您没有考虑“复制到RAMDisk”和“从RAMDisk复制”时间。将RAM专用于固定大小的ramdisk只会减少可用于缓存的内存。操作系统更清楚地知道RAM需要什么。

答案 7 :(得分:2)

  1. 个人资料。确保您对每个选项都做了很好的衡量。您甚至可以购买已经拒绝的东西,测量它们并返回它们,这样您就知道自己正在处理好的数据。

  2. 获取大量内存。 2 GB DIMM非常便宜; 4 GB DIMM略高于100美元/ ea,但与几年前的计算机部件相比,这仍然不是很多钱。无论你最终得到一个RAM磁盘还是让操作系统做它的事情,这都会有所帮助。如果您运行的是32位Windows,则需要切换到64位才能使用超过3 GB的任何内容。

  3. Live Mesh 可以从本地RAM驱动器同步到云端或另一台计算机,为您提供最新的备份。

  4. 仅移动编译器输出。将源代码保存在真实物理磁盘上,但直接在RAM驱动器上创建.obj,.dll和.exe文件。

  5. 考虑DVCS从实际驱动器克隆到RAM驱动器上的新存储库。经常将您的更改“推送”给父母,比如每次测试都通过。

答案 8 :(得分:2)

我有同样的想法并做了一些研究。我发现以下工具可以满足您的需求:

然而,第二个我根本无法在64位Windows 7上工作,而且现在似乎没有维护。

另一方面,VSuite RAM磁盘工作得非常好。不幸的是,与SSD光盘相比,我无法衡量任何显着的性能提升。

答案 9 :(得分:2)

是的,我遇到了同样的问题。在毫无结果的谷歌搜索后,我刚刚写了一个Windows服务,用于懒惰备份RAM驱动器(实际上 - 任何文件夹,因为RAM驱动器可以安装在例如桌面上)。

http://bitbucket.org/xkip/transparentbackup 您可以指定完全扫描的间隔(默认为5分钟)。 并且只扫描通知文件的间隔(默认为30秒)。 扫描使用'archive'属性检测已更改的文件(操作系统会重置该文件专门用于存档)。仅备份以这种方式修改的文件。

该服务会保留一个特殊的标记文件,以确保目标备份完全是源的备份。如果源为空且不包含标记文件,则该服务将从备份执行自动还原。因此,您可以轻松销毁RAM驱动器并通过自动数据恢复再次创建它。最好使用能够在系统启动时创建分区的RAM驱动器,使其透明地工作。

我最近检测到的另一个解决方案是SuperSpeed SuperCache

该公司还有一个RAM磁盘,但这是另一个软件。 SuperCache允许您使用额外的RAM进行块级缓存(它与文件缓存非常不同),另一个选项 - 镜像您完全驱动到RAM。在任何情况下,您都可以指定将脏块丢弃回硬盘驱动器的频率,在RAM驱动器上进行写入,但镜像方案也可以从RAM驱动器中读取。您可以创建一个小分区,例如2 GB(使用Windows)并将整个分区映射到RAM。

关于该解决方案的一个有趣且非常有用的事情 - 您可以随时通过两次单击立即更改缓存和镜像选项。例如,如果您希望将2 GB用于gamimg或虚拟机 - 您可以立即停止镜像并释放内存。即使打开的文件句柄也不会中断 - 分区继续工作,但作为通常的驱动器。

编辑:我还强烈建议您将TEMP文件夹移动到内存驱动器,因为编译器通常会使用temp进行大量工作。在我的情况下,它给了我另外30%的编译速度。

答案 10 :(得分:1)

我想知道你是否可以构建类似于软件RAID 1的东西,其中你有一个物理磁盘/分区作为成员,以及一大块RAM作为成员。

我打赌稍微调整一些非常奇怪的配置,可以让Linux做到这一点。我不相信这是值得的努力。

答案 11 :(得分:1)

甚至单核机器上的超级优势也是并行制造。磁盘I/O是构建过程中非常重要的因素。每个CPU核心产生两个编译器实例实际上可以提高性能。当一个编译器实例在I / O上阻塞时,另一个通常会跳转到CPU密集的编译部分。

你需要确保你有RAM来支持这个(在现代工作站上不应该是一个问题),否则你最终会交换并失去目的。

GNU make上,您可以使用-j[n],其中[n]是要生成的并发进程数。确保在尝试之前确定了依赖树,或者结果可能无法预测。

另一个非常有用的工具(以并行制作方式)是distcc。它适用于GCC(如果您可以使用GCC或具有类似命令行界面的东西)。 distcc实际上通过伪装成远程服务器上的编译器和生成任务来分解编译任务。你以与调用GCC相同的方式调用它,并且你利用make的-j [n]选项来调用许多distcc进程。

在我之前的一个工作中,我们有一个相当密集的Linux操作系统构建,几乎每天都会执行一段时间。添加几个专用的构建机器并将distcc放在几个工作站上以接受编译作业,这使我们能够将构建时间从半天缩短到60分钟以下,从而构建完整的OS +用户空间。

还有很多其他工具可以加速编译现有的工具。您可能想要研究的不只是创建RAM磁盘;因为操作系统正在使用RAM进行磁盘缓存,所以看起来它将获得很少的收益。操作系统设计人员花费大量时间来获得适合大多数工作负载的缓存;他们(统称)比你聪明,所以我不想尝试做得比他们好。

如果你为RAM磁盘咀嚼RAM,那么操作系统的工作RAM就会减少以缓存数据和运行你的代码 - &gt;你会得到更多的交换和更糟糕的磁盘性能(注意:你应该在完全丢弃它之前描述这个选项)。

答案 12 :(得分:1)

  

周围有很多RAMDrives,请使用其中一个。对不起,这将是鲁莽的。

只有你完全在RAM光盘中工作,这是愚蠢的..

Psuedo-ish shell脚本,ramMake:

# setup locations
$ramdrive = /Volumes/ramspace
$project = $HOME/code/someproject

# ..create ram drive..

# sync project directory to RAM drive
rsync -av $project $ramdrive

# build
cd $ramdrive
make

#optional, copy the built data to the project directory:
rsync $ramdrive/build $project/build

也就是说,您的编译器可以在没有其他脚本的情况下执行此操作。只需将构建输出位置更改为RAM光盘,例如在Xcode中,它位于Preferences,Building,“Place Build Products in:”和“Place”下中级构建文件:“。

答案 13 :(得分:0)

我的头脑中有些想法:

使用Sysinternals'Process Monitor(不是Process Explorer)来检查构建过程中发生了什么 - 例如,这将让您看到是否使用了%temp%(请记住,请回复文件可能是用FILE_ATTRIBUTE_TEMPORARY创建的,尽管如此可能会阻止磁盘写入。我已经将%TEMP%移到了RAM磁盘上,这给了我一般的小幅加速。

获取支持自动加载/保存磁盘映像的RAM磁盘,这样您就不必使用启动脚本来执行此操作。顺序读取/写入单个磁盘映像比同步大量小文件更快。

将常用/大型头文件放在RAM磁盘上,并覆盖编译器标准路径以使用RAM驱动器副本。但是,在首次构建之后,它可能不会给 提供很多改进,因为操作系统会缓存标准头文件。

将源文件保存在硬盘上,并同步到RAM磁盘 - ,而不是相反。检查MirrorFolder是否在文件夹之间进行实时同步 - 它通过过滤器驱动程序实现了这一点,因此只需同步所需(并且只进行更改 - 对4 GB文件进行4 KB写入只会导致4 KB写入到目标文件夹)。弄清楚如何从RAM驱动器进行IDE构建,尽管源文件在硬盘上...并且请记住,对于大型项目,您需要大型 RAM驱动器

答案 14 :(得分:0)

您发生的磁盘减速主要是写入,也可能是由于病毒扫描程序造成的。操作系统之间的差异也很大。

由于写入速度最慢,我很想设置一个构建,其中中间(例如,.o文件)和二进制文件输出到不同的位置,例如RAM驱动器。

然后,您可以将此bin / intermediate文件夹链接到更快的媒体(使用symbolic linkNTFS junction point)。

答案 15 :(得分:0)

这听起来就像您的操作系统和/或硬盘驱动器将自动处理的磁盘缓存(不可否认,性能不同)。

我的建议是,如果你不喜欢你的驱动器的速度,购买高速驱动器纯粹是为了编译目的。您可以减少劳动力,并且可以为您的编译工作提供解决方案。

由于最初提出这个问题,与SSD相比,旋转硬盘已成为悲惨的龟。它们非常接近您可以从Newegg或亚马逊购买的SKU中最初请求的RAM磁盘。

答案 16 :(得分:0)

我对此问题的最终解决方案是vmtouch:https://hoytech.com/vmtouch/ 此工具将当前文件夹锁定到(ram)缓存中,并将vmtouch守护程序锁定到后台。

NSData

将它放在shell rc中以便快速访问:

sudo vmtouch -d -L ./

我搜索了一个现成的脚本很长一段时间,因为我不想浪费大量时间编写自己的ramdisk-rsync脚本。我确定我会错过一些边缘情况,如果涉及重要代码,那将是非常不愉快的。我从不喜欢投票方法。

Vmtouch似乎是完美的解决方案。此外,它不像固定大小的ramdisk那样浪费内存。 我没有做基准测试,因为我的1Gig源+构建文件夹的90%已经被缓存,但至少感觉更快;)

答案 17 :(得分:-1)

正如James Curran所说,大多数程序遵循引用的局部性规则,频繁的代码和数据页数将随着时间的推移缩小到操作系统磁盘缓存的可管理大小。

当操作系统构建有诸如愚蠢的缓存(Win 3.x,Win 95,DOS)等限制时,RAM磁盘非常有用。 RAM磁盘的优势几乎为零,如果你分配了大量的RAM,它将会占用系统缓存管理器可用的内存,从而损害整体系统性能。经验法则是:让你的内核去做。这与“内存碎片整理”或“优化器”程序相同:它们实际上会强制页面超出缓存(因此最终会获得更多RAM),但是当您加载的程序时,会导致系统出现大量页面错误开始询问被分页的代码/数据。

因此,为了获得更高的性能,请获得快速磁盘I / O硬件子系统,可能是RAID,更快的CPU,更好的芯片组(没有VIA!),更多的物理RAM等。