如何增加Matlab的Ubuntu虚拟内存和/或交换?


16

情况:修复Out of MemoryUbuntu的Matlab中的错误
目标:在外部HDD / SSD上分配一些虚拟内存和/或交换;读/写从20 GBps减少到0.1 GBps,没关系!
术语:此处交换和虚拟内存

不,交换和虚拟内存完全不同。例如,映射1GB文件的内存使用了额外的1GB虚拟内存,但是交换的使用没有变化。交换是后备存储的一种形式。虚拟内存的许多用途与后备存储无关。(并且曾经有没有虚拟内存且没有交换的系统以及有交换但没有虚拟内存的系统。)

消费类硬件有限,因此我需要使用更多的虚拟内存和/或与外部HDD交换。Matlab关于交换内存(TODO不包括虚拟内存?)

Linux系统—使用mkswapswapon命令更改交换空间。

系统特点

  • 你可以看到你有多少 swapon -s

    Filename                Type        Size    Used    Priority
    /dev/sda3               partition   8326140 0       -1
    
  • Matlab的配置

    % /programming//a/35971040/54964
    com.mathworks.services.Prefs.setIntegerPref('JavaMemHeapMax', 2048); % MB
    
    % TODO cannot find ways how to put Matlab use /dev/sda3
    
  • 因此,您看到我的Matlab没有使用它。我Out of Memory在Matlab中收到大型矩阵的错误。在将reshape矩阵矩阵转换为向量并编写并行代码方面,我一直没有成功。所以我想使用虚拟内存,因为我需要完成工作。速率无关紧要。

伪码

  1. 用于创建交换,启动MATLAB并在MATLAB退出时删除交换的Shell脚本。(MichaelHooreman
  2. 在外部硬盘上启用交换。如何在sudo swapon -a这里使用?
  3. 启动Matlab。
  4. 把Matlab使用掉。
  5. Matlab退出时删除交换。

Micheal脚本中的临时交换,运行客户端以及关闭/删除交换

情况:无法控制设置环境(1),运行Matlab(2)和关闭环境(3)
脚本中的错误

#!/usr/bin/env bash

# /programming//a/69808/54964
set -e 
# TODO How to do swapoff if any error?

SWAP_FILE="/media/masi/SamiSwapVirtual/.swap_file_20.7.2016"
SIZE_MB=16000
TO_RUN="matlab"

dd if="/dev/zero" of=${SWAP_FILE} bs="1M" count=${SIZE_MB} status="progress"
mkswap ${SWAP_FILE}
chmod 0600 ${SWAP_FILE}
sudo chown 0.0 ${SWAP_FILE} # /unix//a/297153/16920
sudo swapon -v ${SWAP_FILE}
echo "Swap enabled. Press enter to continue"; read
${TO_RUN}
echo "I will remove the swap. Press enter to continue"; read
sudo swapoff -v ${SWAP_FILE}
rm -vf ${SWAP_FILE}

具有Transcend 25M3 1 TB的迭代1,在文件系统很少使用的情况下 ext4

  1. 启动脚本后的日志

    sh start_matlab_with_swap.sh 
    16000+0 records in
    16000+0 records out
    16777216000 bytes (17 GB, 16 GiB) copied, 134.489 s, 125 MB/s
    Setting up swapspace version 1, size = 15.6 GiB (16777211904 bytes)
    no label, UUID=48c2835b-4499-4534-aa49-0648e15bd5d9
    [sudo] password for masi: 
    swapon /media/masi/SamiWeek/tmp/swap_file_18.7.2016
    swapon: /media/masi/SamiWeek/tmp/swap_file_18.7.2016: insecure file owner 1000, 0 (root) suggested.
    swapon: /media/masi/SamiWeek/tmp/swap_file_18.7.2016: found swap signature: version 1d, page-size 4, same byte order
    swapon: /media/masi/SamiWeek/tmp/swap_file_18.7.2016: pagesize=4096, swapsize=16777216000, devsize=16777216000
    Swap enabled. Press enter to continue
    start_matlab_with_swap.sh: 11: read: arg count
    
  2. 运行客户端

    • 命令历史记录在交换存储器的Matlab的第一个起始位置(票号#02075943)中,出现错误读取命令历史记录--时出现问题。只需重新启动Matlab,如果您使用默认设置即可解决问题。命令prefdir给出的/home/masi/.matlab/R2016a是默认位置(/home/{username}/.matlab/R2016a/home/masi/.matlab/R2016a/matlab.prf重新启动后文件存在,此处

    • ... [其他错误] ...

  3. 关闭Matlab并在终端中再次输入密码

    [sudo] password for masi: 
    swapoff /media/masi/SamiWeek/tmp/swap_file_18.7.2016
    [ bugs here! ]
    

开放:如何在此处应用更好的错误捕获错误处理?请参阅我的脚本以获取源代码中的示例。线程如果发生错误/警告,如何进行错误捕获和交换?

永久交换=与运行客户端分开的交换设置

设置交换

# /unix//q/297767/16920
masi@masi:~$ sudo fallocate -l 20G /mnt/.swapfile

masi@masi:~$ sudo mkswap /mnt/.swapfile 
Setting up swapspace version 1, size = 20 GiB (21474832384 bytes)
no label, UUID=45df9e48-1760-47e8-84d7-7a14f56bbd72

masi@masi:~$ sudo swapon /mnt/.swapfile
swapon: /mnt/.swapfile: insecure permissions 0644, 0600 suggested.

masi@masi:~$ sudo chmod 600 /mnt/.swapfile

masi@masi:~$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7925        1494         175         196        6255        5892
Swap:         28610           0       28610

/etc/fstab在永久更改的末尾添加以下内容

# /unix//a/298212/16920
# /unix//a/298543/16920

# If swap is on SSD, trim blocks each time at startup.
#/mnt/.swapfile  none    swap    defaults,discard      0        0

# If swap on External HDD, just use sw.
/media/masi/SamiWeek/.swapfile  none    swap    sw      0        0

系统:Linux Ubuntu 16.04 64位
Linux内核:4.6
Linux内核选项:wl
Matlab:2016a
官方Matlab文档:解决“内存不足”错误
外部硬盘驱动器:Transcend 1 TB StoreJet 25M3 评估,Transcend 2 TB StoreJet 25M3
外部HDD文件系统:ext4
外部HDD缓冲区:8 MB
相关线程:如何增加Ubuntu中的MATLAB内存限制?(如何使用MATLAB的mkswap,swapon?)如何减少Matlab中的物理内存增加?如何解决Matlab中的内存不足错误?如何修复Matlab中10800x10800矩阵的内存不足错误?如何在Matlab r2012b中增加内存限制(连续的和整体的)?如何在Matlab 2009b中增加阵列块并解决内存不足错误?如何解决Matlab中一个小变量的内存不足问题?在Matlab中为“内存不足”。一个缓慢但永久的解决方案?


4
抱歉,这不能回答问题。但是您确定要吗?通过交换执行计算花费了令人难以置信的时间。Ram至少每秒读取20 GB,您的外部HDD读取速度将低于0.1 GBps
Anake

1
@ Anake是的,我知道。这不成问题。我有巨大的矩阵,可以用32/64 GB来计算,但不能用当前的8 GB超极本来计算。我仍然需要在假期中进行计算。
莱奥波德·赫兹(LéoLéopoldHertz)2016年

1
另一条无用的评论表示抱歉。您能否将计算机留在家中,以便可以通过SSH在家中或Uni上运行它们?
阿纳克

@Anake目前无法,抱歉。另外,这里的Matlab因此需要局部计算。另外,目前没有足够的键可以执行此操作。
莱奥波德·赫兹(LéoLéopoldHertz)2016年

在这种情况下,MATLAB有何特别之处?这不只是如何增加交换空间
钢铁司机

Answers:


2

好的,这里有一个清单。让我内联回复

  1. 如何在此处应用更好的错误捕获错误处理?请参阅我的脚本以获取源代码中的示例。线程如果发生错误/警告,如何进行错误捕获和交换?

我根本不喜欢这个脚本的概念。您有一个试图用作交换的外部硬盘驱动器只是一个坏主意。如果您确实打算定期执行此操作,请调整分区的大小以放入适当的交换分区,添加交换文件或只是购买更大的内部磁盘。

  1. 如果矩阵大小超过交换大小,如何发出警告?

只是做数学。如果您在程序开始之前知道矩阵的大小,请在MiB中计算大小并将其与可用交换进行比较。

  1. 如何在Matlab中计算巨大矩阵时拥有进度条?

matlab有API吗?我认为这不是解决该问题的合适论坛。即使您拥有API,也会通过交换阻塞IO,因此它只是一个缓慢的进度条,实际上并不能反映现实情况。

  1. 如何在迭代(2)中终止繁忙的进度和/或swapon -s / swapoff?

你不知道 仅仅因为您已完成计算,并不意味着操作系统已使用您分配的资源完成。写完交换内容后,它将释放。您已经消耗了太多的内存,以至于许多应用程序无法获得所需的内存,因此它们也在使用交换功能。只需将其保留,然后由操作系统来完成即可。在执行下一次运行之前,请清除缓存。

echo 3 > /proc/sys/vm/drop_caches 

可能还有更多,我不是Linux VM专家。研究SLAB / SLUB分配器的工作方式以及如何针对您的大内存需求进行调优是值得的。您可能可以将matlab MLOCK到内存中。这迫使操作系统为您保留内存,或者它只是没有启动,完成后还必须将其解锁。我可以使用C API很好地做到这一点,但是我不确定您将如何在无法重新编译的过程之外进行该工作,这需要进行一些研究。

最后,这就是EC2的用途。看来您需要的是16G,一个m4.4xlarge具有64G内存@每小时$ 0.958。少于一杯咖啡。使用juju charm或类似的脚本编写安装的matlab脚本,然后将整个过程变成服务即计算。

16G是16 GB吗?

  • 是的,通常在不使用后缀时,我们指的是以字节为单位的base2数字。如果您想简明扼要,您可以编写16GiB。

“我需要大于100 GB的矩阵。我不知道您是否可以使用EC2做到这一点。”

您还应该清除缓存echo 3 > /proc/sys/vm/drop_caches吗?

  • 是的,始终这样做不会有任何伤害。请参阅Linux内核中的Documentation / sysctl / vm.txt。

您如何将Matlab MLOCK插入内存?

  • man mlock。虽然我引用那句话时很无聊。该调用确保您可以分配所需的所有内存,并且不会被交换掉,它永远不会使用虚拟内存。那不是你想要的。

我认为您可以将C API绑定到Matlab。--如果流程中有任何故障,您是否打算关闭交换?

  • 我要坦率地说,以您提出的方式微管理交换文件的概念是荒谬的。操作系统的工作是管理资源并以公平一致的方式分发资源。一旦为它提供了更多资源,它将根据需要使用它们。完成后,您不必告诉它,也不必从其下面抽出资源,操作系统会告诉您完成的时间。

当我向OS询问内存地址空间时,有时它并不总是成功,这并不意味着我无法再尝试。matlab无法弄清楚两次调用malloc是matlab的问题。

因此,要影响您想要的更改,如果那100G的空间确实非常宝贵,那么您需要弄清楚如何告诉操作系统减少其内存占用(通过清除启动程序的缓存),以便内存管理器不会觉得有必要使用它提供的其他交换空间。然后只有这样,您才能要求内存管理器释放交换文件。

增长内存和磁盘之类的东西很容易,而缩小它们的难度则更大。缩小迫使重新分配在该空间中分配了资源的每个用户。如果我改为说“我有一个100TB的存储阵列,但是现在我只需要60TB,那么为什么当我删除40TB的磁盘时该阵列停止工作?” 好吧,答案很明显吧?

因此,我认为这是您的选择。

  1. 研究matlab C API,以查看是否可以更好地控制如何为这些庞大的工作集分配内存。

  2. 重构您的计算以使用子矩阵或其他稀疏数据表示来计算您现在拥有的内容。

  3. 使用大量的线性代数库在C / C ++中编写自己的程序,以执行计算并使用mallocmmap匿名分配所需的地址空间。


是的,但这可能还不够,如果成功的话,您可能必须等待重试才能成功。
ppetraki '16

1
嘿,您的其余评论未显示在我的智能手机中。您不能像这样进行sudo echo,而是这样做。echo 3 | sudo tee /proc/sys/vm/drop_caches
ppetraki '16

我接受这个答案,因为它的答案是正确的。在与设置环境相同的脚本中运行Client极易出错。在这里,有关它的更多讨论unix.stackexchange.com/a/298543/16920--如果您几乎不打扫身体,那将是很好的。
莱奥波德·赫兹(LéoLéopoldHertz)2016年

12

您不能专用于软件交换。您可以做的是创建一个shell脚本,该脚本创建一个交换,启动MATLAB,并在MATLAB退出时删除该交换。

这是一个示例脚本,该脚本在/ tmp目录中创建10Mb交换,将其安装,启动R(我没有matlab),等待R退出,卸载交换文件并删除它。

请注意:-您将收到警告,因为交换文件不是root用户所有。那是因为系统将使用任何软件(也许不是由您运行),并且您可以读取该文件...我让您对其进行修复。-如果您[ctrl]-[c]脚本或注销等,交换将保持挂载状态。我也让您修复它。

#!/usr/bin/env bash

SWAP_FILE=/tmp/my_swap_file
SIZE_MB=10
TO_RUN="R"

dd if=/dev/zero of=${SWAP_FILE} bs=1M count=${SIZE_MB}
mkswap ${SWAP_FILE}
chmod 0600 ${SWAP_FILE}
sudo swapon -v ${SWAP_FILE}
echo "Swap enabled. Press enter to continue"; read
${TO_RUN}
echo "I will remove the swap. Press enter to continue"; read
sudo swapoff -v ${SWAP_FILE}
rm -vf ${SWAP_FILE}

1
好吧,它不是真正专用于MATLAB的,而是用于需要临时增加RAM的任何情况。请注意,swapon / swapoff需要root权限(因此:sudo)
Michael Hooreman

1
是的,你有。那就是如何成为根。
Michael Hooreman '16

好答案。我个人接近它,这是和保持我自己的add-swap.sh脚本thise可爱的时刻,当内存被吃掉了
谢尔盖Kolodyazhnyy

我在这里授予赏金是因为它使我成为正确的方式。但是,我无法接受答案,因为错误管理非常困难且不完整。最好是建立运行Matlab的单独交换,请在这里看到答案unix.stackexchange.com/a/298543/16920
莱奥列奥波尔德·赫兹준 영

1

这是使用外部硬盘驱动器扩展SWAP内存的方法:

  • 首先,通过运行以下命令记录实际的SWAP内存:

    free -m
    
  • 其次,准备好硬盘的文件夹。应该是这样的/media/myhdd

  • 确定要添加的额外SWAP的大小。假设是X GB。
  • 计算该数量为多少个字节。使用GB,这是:Y = X * 1024 ^ 3,其中Y是您的计算结果。
  • 选择文件的块大小(以字节为单位)。让我们在这里使用默认值:4096(有关更多信息,请参见此处)。
  • 计算文件将具有的块数:Z = Y / 4096
  • 在终端中使用以下命令创建大小为X GB 的文件:

    dd if=/dev/zero of=/media/myhdd/swapfile bs=4096 count=Z
    
  • 使用以下命令在文件中创建SWAP:

    sudo mkswap /media/myhdd/swapfile -f
    
  • 最后,启用SWAP:

    sudo swapon -p 1000 /media/myhdd/swapfile
    

现在您的SWAP增加了。再次检查free -m


我们可以在非交互式脚本中进行设置(sudo需要电源):

#!/bin/bash

### Inputs ###

swap_GB=$(expr 1) # Enter here size of the swap memory to create, in GB.
swap_bs=$(expr 4096) # Enter here block size, in bytes (must be a multiple of 8).
HDD_folder="/media/myhdd/" # Enter absolute path of HDD inside the brackets.

### Swap creation ###

swap_size=$(expr $swap_GB \* 1024 \* 1024 \* 1024 / $swap_bs)
dd if=/dev/zero of=${HDD_folder}"/swapfile" bs=$swap_bs count=$swap_size
mkswap ${HDD_folder}"/swapfile" -f
swapon -p 1000 ${HDD_folder}"/swapfile"

### EOF ###

PS:请尽可能优化/更正。如前所述,这是我的第一个脚本:)


好吧,交换已经很慢了,但是我无法想象在USB驱动器上进行交换。它将变得像地狱般缓慢恕我直言
Michael Hooreman '16

作为摘要的脚本在这里很棒。
莱奥波德·赫兹(LéoLéopoldHertz)2016年

1
我从未创建过脚本,但可以尝试一下。

1

我至少会测试压缩RAM(zram内核模块,自3.14版以来提供)的性能。

遵循archlinux Wiki指示

modprobe zram
echo lz4 > /sys/block/zram0/comp_algorithm
echo 4G > /sys/block/zram0/disksize
mkswap --label zram0 /dev/zram0
swapon --priority 100 /dev/zram0

我的猜测是压缩RAM应该比磁盘I / O快。

要在重新启动后也保留更改,请放入boot time命令/etc/rc.local并运行sudo systemctl enable rc-local.service


我将答案扩展到线程unix.stackexchange.com/q/297752/16920,以了解zram对内存大小和分页速率的影响。我找不到对内存大小的任何影响,可能主要是在页面调度上。但是,rund增加了systemd / ...警告。知道zram的错误率会很高兴。
莱奥波德·赫兹(LéoLéopoldHertz)2016年

如果使用zram0,则/ sys / block / zram0中的orig_data_sizecompr_data_size文件中提供了一些统计信息。我那里没有交换太多数据,但那里的比率约为0.35。以该比率,11 GB的数据可能适合4 GB的RAM。这可能意味着7 GB的数据未交换到磁盘。
JJ Hakala

1
您可以在/etc/rc.local中放置启动时间命令,然后sudo systemctl enable rc-local.service
JJ Hakala

我发现zram不适用于在HDD / SSD互换所以zram在这里不适用,请参阅线程askubuntu.com/a/472227/25388
莱奥列奥波尔德·赫兹준 영

1

zswap如果您在HDD / SSD上有交换部分,请使用。该模块zram在HDD / SSD上没有交换部分,因此Hakala的答案不适用。请参阅线程zram vs zswap vs zcache Ultimate指南:何时使用哪一个进行解释。设置zswap在线程描述在Ubuntu 16.04如何激活Zswap成功地为Matlab的计算?

  • 将相应的行替换为 /etc/default/grub

    # https://wiki.archlinux.org/index.php/Zswap
    GRUB_CMDLINE_LINUX_DEFAULT="quiet splash zswap.enabled=1 zswap.max_pool_percent=25 zswap.compressor=lzo"
    
  • 运行sudo update-grub

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.