Использование всей доступной оперативной памяти в программе Haskell?
У меня 8 ГБ оперативной памяти, но программы Haskell, по-видимому, могут использовать только 1,3 ГБ.
Я использую эту простую программу, чтобы определить, сколько памяти может выделить программа GHC:import System.Environment
import Data.Set as Set
main = do
args <- getArgs
let n = (read $ args !! 0) :: Int
s = Set.fromList [0..n]
do
putStrLn $ "min: " ++ (show $ findMin s)
putStrLn $ "max: " ++ (show $ findMax s)
Вот что я нахожу:
- запуск
./mem.exe 40000000 +RTS -s
выполняется успешно и сообщает1113 MB total memory in use
- запуск
./mem.exe 42000000 +RTS -s
завершается неудачей сout of memory error
- запуск
./mem.exe 42000000 +RTS -s -M4G
ошибок с-M4G: size outside allowed range
- выполняется
./mem.exe 42000000 +RTS -s -M3.9G
выдаетout of memory error
Мониторинг процесса с помощью Диспетчера задач Windows показывает, что максимальное использование памяти составляет около 1,2 ГБ.
Моя система: Win7, 8 ГБ оперативной памяти, платформа Haskell 2011.04.0.0, ghc 7.0.4.
Я компилирую с: ghc -O2 mem.hs -rtsopts
Как я могу использовать всю мою доступную оперативную память? Я упускаю что-то очевидное?
2 ответа:
В настоящее время в Windows GHC является 32-разрядным GHC - я думаю, что 64-разрядный GHC для windows должен быть доступен, когда появится 7.6.
Одним из следствий этого является то, что в Windows вы не можете использовать больше
4G - 1BLOCK
памяти, так как максимально допустимым параметром размера являетсяHS_WORD_MAX
:decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE;
С 32-битными словами,
HS_WORD_MAX = 2^32-1
.Это объясняет
Бег ./память.exe 42000000 +RTS-s-M4G ошибки out with-M4G: размер вне допустимого диапазона
С тех пор
decodeSize()
декодирует4G
как2^32
.Это ограничение сохранится и после обновления вашего GHC, пока, наконец, не будет выпущен 64-битный GHC для Windows.
Как 32-разрядный процесс, виртуальное адресное пространство пользовательского режима ограничено 2 или 4 ГБ (в зависимости от состояния флага
Теперь вы пытаетесь построитьIMAGE_FILE_LARGE_ADDRESS_AWARE
), CFограничения памяти для выпусков Windows .Set
, содержащий 42 миллиона 4-байтовыхInt
s. aData.Set.Set
имеет пять слов накладных расходов на элемент (конструктор, размер, указатель на левое и правое поддерево, указатель на элемент), поэтомуSet
займет около 0,94 гигабайта памяти (1,008 "метрического" ГБ). Но процесс использует примерно в два раза больше или больше (ему нужно пространство для сборки мусора, по крайней мере, размер живой кучи).Запустив программу на моем 64-битном linux, с вводом 21000000 (чтобы компенсировать вдвое большие
Int
s и указатели), я получаю$ ./mem +RTS -s -RTS 21000000 min: 0 max: 21000000 31,330,814,200 bytes allocated in the heap 4,708,535,032 bytes copied during GC 1,157,426,280 bytes maximum residency (12 sample(s)) 13,669,312 bytes maximum slop 2261 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 59971 colls, 0 par 2.73s 2.73s 0.0000s 0.0003s Gen 1 12 colls, 0 par 3.31s 10.38s 0.8654s 8.8131s INIT time 0.00s ( 0.00s elapsed) MUT time 12.12s ( 13.33s elapsed) GC time 6.03s ( 13.12s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 18.15s ( 26.45s elapsed) %GC time 33.2% (49.6% elapsed) Alloc rate 2,584,429,494 bytes per MUT second Productivity 66.8% of total user, 45.8% of total elapsed
Но
top
сообщает только1.1g
Об использовании памяти -top
, и предположительно Диспетчер задач, сообщает только живая куча.Таким образом, кажется, что
IMAGE_FILE_LARGE_ADDRESS_AWARE
Не задано, ваш процесс ограничен адресным пространством 2 ГБ, и 42 миллионаSet
требуется больше, чем это - если вы не укажете Максимальный или предполагаемый размер кучи, который меньше:$ ./mem +RTS -s -M1800M -RTS 21000000 min: 0 max: 21000000 31,330,814,200 bytes allocated in the heap 3,551,201,872 bytes copied during GC 1,157,426,280 bytes maximum residency (12 sample(s)) 13,669,312 bytes maximum slop 1154 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 59971 colls, 0 par 2.70s 2.70s 0.0000s 0.0002s Gen 1 12 colls, 0 par 4.23s 4.85s 0.4043s 3.3144s INIT time 0.00s ( 0.00s elapsed) MUT time 11.99s ( 12.00s elapsed) GC time 6.93s ( 7.55s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 18.93s ( 19.56s elapsed) %GC time 36.6% (38.6% elapsed) Alloc rate 2,611,793,025 bytes per MUT second Productivity 63.4% of total user, 61.3% of total elapsed
Устанавливая максимальный размер кучи ниже того, что он использовал бы естественно, фактически позволяет ему поместиться едва ли больше, чем пространство, необходимое для
Set
, ценой немного большего времени GC и предлагая размер кучи-H1800M
позволяет ему закончить использование толькоПоэтому, если вы зададите максимальный размер кучи ниже 2 ГБ (но достаточно большой, чтобы1831 MB total memory in use (0 MB lost due to fragmentation)
Set
поместился), это должно сработать.
Размер кучи по умолчаниюне ограничен .
Используя GHC 7.2 на 64-битной машине Windows XP, я могу выделить более высокие значения, установив размер кучи больше, явно:
$ ./A 42000000 +RTS -s -H1.6G min: 0 max: 42000000 32,590,763,756 bytes allocated in the heap 3,347,044,008 bytes copied during GC 714,186,476 bytes maximum residency (4 sample(s)) 3,285,676 bytes maximum slop 1651 MB total memory in use (0 MB lost due to fragmentation)
И
$ ./A 42000000 +RTS -s -H1.7G min: 0 max: 42000000 32,590,763,756 bytes allocated in the heap 3,399,477,240 bytes copied during GC 757,603,572 bytes maximum residency (4 sample(s)) 3,281,580 bytes maximum slop 1754 MB total memory in use (0 MB lost due to fragmentation)
Даже:
$ ./A 42000000 +RTS -s -H1.85G min: 0 max: 42000000 32,590,763,784 bytes allocated in the heap 3,492,115,128 bytes copied during GC 821,240,344 bytes maximum residency (4 sample(s)) 3,285,676 bytes maximum slop 1909 MB total memory in use (0 MB lost due to fragmentation)
То есть, я могу выделить до предела процесса Windows XP 2G. Я думаю, что на Win 7 у вас не будет такого низкого лимита-эта таблица предполагает либо 4G, либо 192G - просто попросите столько, сколько вам нужно (и используйте более свежий GHC).