55

Stack Overflow 上的一个问题的答案 (见下文)让我想到了一个很棒的小软件,它对世界各地的编码人员来说都是无价的。

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

快速的谷歌搜索什么也没发现,但也许我只是不知道如何谷歌。也许有人知道这样的软件?最好是免费的,但合理的费用也可以。

补充:已经提出了一些我一开始就放弃的解决方案。它们将是(无特定顺序):

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

补充 2:一个想法出现了 - 使用普通的 RAM 驱动器加上一个后台文件夹同步器(但我的意思是background)。有没有这样的事情?

补充3:有趣。我刚刚在工作中试用了一个简单的 RAM 驱动器。重建时间从 ~14 秒下降到 ~7 秒(还不错),但增量构建仍然在 ~5 秒 - 就像在 HDD 上一样。任何想法为什么?它使用aspnet_compileraspnet_merge。也许他们对其他地方的其他临时文件做了一些事情?

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

产生这个想法的主要原因之一不是上述软件(构建时间为 14 秒),而是我当时无法访问的另一个软件。这个另一个应用程序有一个 100 MB 的代码库,它的完整构建大约需要 5 分钟。啊,是的,它在Delphi 5中,所以编译器不是太先进。:) 将源放在 RAM 驱动器上会产生很大的不同。我想不到一分钟就知道了。我没有量过。因此,对于所有那些说操作系统可以更好地缓存内容的人——我不敢苟同。

相关问题:

用于加速 IDE 的 RAM 磁盘

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

编译代码时你在做什么?

我链接到的Dmitri Nesteruk的答案是:

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

4

18 回答 18

20

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

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

例如,您可以将其设置为拥有~/code~/code-real。您的 RAM 块~/code在启动时安装,然后~/code-real(在标准硬盘上)中的所有内容都会被复制。关机时,所有内容都将被复制(rsync会更快)~/code~/code-real. 您可能还希望该脚本定期运行,因此在电源故障等情况下您不会丢失太多工作。

我不再这样做了(当 9.5 测试版运行缓慢时,我将它用于Opera ,不再需要了)。

这是在 Linux 中创建 RAM 磁盘的方法。

于 2008-12-09T22:58:59.560 回答
16

我很惊讶有多少人建议操作系统在确定缓存需求方面比在这种特殊情况下做得更好。虽然我没有为编译执行此操作,但我确实为类似的过程执行了此操作,最终我使用了带有脚本的 RAM 磁盘来自动同步。

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

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

高兴时进行最后检查,您甚至不必使用常规硬盘驱动器。

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

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

于 2009-03-27T04:03:35.140 回答
7

请参阅使用 tmpfs 加速emergeGentoo Linux wiki)。

在 Gentoo 下使用 RAM 驱动器加速编译是许多年前编写的操作指南的主题。它提供了一个具体的例子来说明已经做了什么。要点是所有源文件和构建中间文件都被重定向到 RAM 磁盘进行编译,而最终的二进制文件被定向到硬盘驱动器进行安装。

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

我希望这会有所帮助。

于 2008-12-10T00:28:48.023 回答
4

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

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

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

我相信这种通用解决方案胜过为非常简单的事情制定独特的解决方案。吻

确保将路径更改为 rdbackupd

内存目录

#!/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" &

乌拉姆迪尔

#!/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;
}
于 2011-10-25T23:00:42.823 回答
3

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

于 2008-12-09T21:32:27.910 回答
3

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

DRAM 磁盘具有双 SATA-300 端口,并且在大多数测试中平均寻道时间为 0.0 毫秒;) 圣诞袜有什么用吗?

于 2008-12-09T21:41:05.663 回答
2
  1. 轮廓。 确保您对每个选项都进行了良好的测量。您甚至可以购买您已经拒绝的东西,对其进行测量,然后将其退回,因此您知道您正在使用良好的数据。

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

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

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

  5. 考虑一个DVCS 从真实驱动器克隆到 RAM 驱动器上的新存储库。经常将您的更改“推送”回父级,例如每次所有测试都通过时。

于 2008-12-09T23:31:22.320 回答
2

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

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

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

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

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

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

编辑:我还强烈建议您将 TEMP 文件夹移动到 te RAM 驱动器,因为编译器通常会使用 temp 进行大量工作。就我而言,它又给了我 30% 的编译速度。

于 2012-03-11T06:31:57.507 回答
2

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

于 2008-12-09T21:38:06.137 回答
2

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

但是,第二个我根本无法在 64 位 Windows 7 上工作,而且目前似乎没有得到维护。

另一方面,VSuite RAM 磁盘运行良好。不幸的是,与现有的SSD磁盘相比,我无法衡量任何显着的性能提升。

于 2011-11-09T19:33:03.637 回答
1

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

我打赌通过一些调整和一些非常奇怪的配置可以让 Linux 做到这一点。不过,我不相信这值得付出努力。

于 2008-12-10T00:06:34.433 回答
1

周围有很多 RAMDrive,请使用其中之一。对不起,那将是鲁莽的。

仅当您完全在 RAM 磁盘中工作时,这很愚蠢..

伪 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 Intermediate Build Files在:”。

于 2009-03-27T05:31:20.233 回答
1

即使在单核机器上也可能超级有益的是并行制造。磁盘I/O在构建过程中是一个相当大的因素。每个 CPU 内核生成两个编译器实例实际上可以提高性能。由于一个编译器实例在 I/O 上阻塞,另一个通常可以跳转到编译的 CPU 密集部分。

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

GNU make上,您可以使用-j[n]where[n]是同时产生的进程数。在尝试之前确保你有你的依赖树,否则结果可能是不可预测的。

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

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

还有很多其他工具可以加速现有的编译。您可能想要调查的不仅仅是创建 RAM 磁盘;由于操作系统正在使用 RAM 进行磁盘缓存,因此看起来它的收益很小。操作系统设计人员花费大量时间为大多数工作负载正确缓存;他们(集体)比你聪明,所以我不想尝试比他们做得更好。

如果您为 RAM 磁盘咀嚼 RAM,则操作系统用于缓存数据和运行代码的工作 RAM 较少 -> 您最终会得到更多的交换和更差的磁盘性能(注意:您应该在完全丢弃之前配置此选项它)。

于 2009-03-27T04:29:41.693 回答
1

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

sudo vmtouch -d -L ./

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

alias cacheThis = 'sudo vmtouch -d -L ./'

我找了一个现成的脚本很长一段时间,因为我不想浪费很多时间来编写自己的 ramdisk-rsync-script。我敢肯定我会错过一些边缘情况,如果涉及到重要代码,那将是非常不愉快的。而且我从不喜欢投票方式。

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

于 2017-08-02T10:08:00.753 回答
0

我脑子里冒出的一些想法:

使用 Sysinternals 的Process Monitor(不是Process Explorer)来检查构建过程中发生的事情 -%temp%例如,这将让您查看是否使用了(请记住,响应文件可能是使用 FILE_ATTRIBUTE_TEMPORARY 创建的,如果可能的话,它应该防止磁盘写入,尽管)。我已经将我的移动%TEMP%到一个 RAM 磁盘,这通常会给我带来轻微的加速。

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

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

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

于 2009-03-27T05:16:45.917 回答
0

这听起来像是您的操作系统和/或硬盘驱动器会自动为您处理的磁盘缓存(诚然,性能会有所不同)。

我的建议是,如果您不喜欢驱动器的速度,请购买纯粹用于编译目的的高速驱动器。减少您的劳动,您可能会找到解决编译问题的方法。

自从最初提出这个问题以来,与 SSD 相比,旋转硬盘已成为可怜的乌龟。它们与您可以从 Newegg 或 Amazon 购买的 SKU 中最初请求的 RAM 磁盘非常接近。

于 2008-12-09T21:16:15.760 回答
0

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

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

然后,您可以将此 bin/intermediate 文件夹链接到更快的媒体(使用符号链接NTFS 连接点)。

于 2011-09-27T21:36:58.297 回答
-2

正如 James Curran 所说,事实上大多数程序都遵循引用的局部性定律,频繁的代码和数据页计数将随着时间的推移而缩小到 OS 磁盘缓存可管理的大小。

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

所以为了获得更高的性能,获得一个快速的磁盘 I/O 硬件子系统,也许是 RAID、更快的 CPU、更好的芯片组(没有 VIA!)、更多的物理 RAM 等等。

于 2009-03-27T03:51:19.630 回答