Последнее замечание
Оставив свои тесты на потомство, но у тел есть ответ.
Примечание
Ниже приведены результаты тестирования Debian.Тестирование на Ubuntu (WSL) действительно намного хуже.В Ubuntu n=193
для любых сбоев фигур (также, если я заменю 3d n
на 1) и любые n
выше.Выглядит как (см. bla.py
ниже):
py bla.py n 1
выделяет 3204 на A
, 29323 ob B
для всех 0<n<193
- Для
n>=193
aОшибка сегментации возникает на B
, а 3208
выделяется на A
.Видимо, где-то в ubuntu
.
есть некоторый жесткий предел памяти. Старые тесты на Debian
После некоторого тестирования это выглядит какпроблема памяти со странным масштабированием выделения памяти с измерением.
Редактирование только с двумя измерениями не дает мне сбоя, а 3 делает - я отвечу, предполагая это.
Для меня:
b = sharedctypes.RawArray(a._type_, a)
не завершится сбоем, если:
a = np.ctypeslib.as_ctypes(np.zeros((224**3))) #Though generating b takes a while
a = np.ctypeslib.as_ctypes(np.zeros((100,100,100)))
Таким образом, кажется, что меньший спрос на память устраняет проблему, но, как ни странно, такое же количество необходимых ячеек водномерный массив работает нормально, поэтому кажется, что происходит что-то более глубокое в памяти.
Конечно, вы используете указатели.Давайте попробуем кое-что (bla.py
):
import tracemalloc
import numpy as np
from sys import argv
from multiprocessing import sharedctypes
n,shape = (int (x) for x in argv[1:])
if shape == 1: shape = n
if shape == 2: shape = (n**2,n)
if shape == 3: shape = (n,n,n)
tracemalloc.start()
a = np.ctypeslib.as_ctypes(np.zeros(shape))
x=tracemalloc.take_snapshot().statistics('lineno')
print(len(x),sum((a.size for a in x)))
b = sharedctypes.RawArray(a._type_, a)
x=tracemalloc.take_snapshot().statistics('lineno')
print(len(x),sum((a.size for a in x)))
В результате:
n shape (a mallocs sum) (b mallocs sum)
>py bla.py 100 1 => 5 3478 76 30147
>py bla.py 100 2 => 5 5916 76 948313
>py bla.py 100 3 => 5 8200 76 43033
>py bla.py 150 1 => 5 3478 76 30195
>py bla.py 150 2 => 5 5916 76 2790461
>py bla.py 150 3 => 5 8200 76 45583
>py bla.py 159 1 => 5 3478 76 30195
>py bla.py 159 2 => 5 5916 76 2937854
>py bla.py 159 3 => 5 8200 76 46042
>py bla.py 160 1 => 5 3478 76 30195
>py bla.py 160 2 => 5 5916 72 2953989
>py bla.py 160 3 => 5 8200 Segmentation fault
>py bla.py 161 1 => 5 3478 76 30195
>py bla.py 161 2 => 5 5916 75 2971746
>py bla.py 161 3 => 5 8200 75 46116
>py bla.py 221 1 => 5 3478 76 30195
>py bla.py 221 2 => 5 5916 76 5759398
>py bla.py 221 3 => 5 8200 76 55348
>py bla.py 222 1 => 5 3478 76 30195
>py bla.py 222 2 => 5 5916 76 5782877
>py bla.py 222 3 => 5 8200 76 55399
>py bla.py 223 1 => 5 3478 76 30195
>py bla.py 223 2 => 5 5916 76 5806462
>py bla.py 223 3 => 5 8200 76 55450
>py bla.py 224 1 => 5 3478 76 30195
>py bla.py 224 2 => 5 5916 72 5829381
>py bla.py 224 3 => 5 8200 Segmentation fault
>py bla.py 225 1 => 5 3478 76 30195
>py bla.py 225 2 => 5 5916 76 5853950
>py bla.py 225 3 => 5 8200 76 55552
У странных вещей (n**2,n)
выделено огромное количество памяти для общего типа,пока нет n**3
или (n,n,n)
.Но это не имеет значения.
a
mallocs согласованы и лишь незначительно зависят от размера, а вовсе не от n
(для проверенных чисел). b
mallocs, помимо того, что имеют высокую форму 2, также немного увеличиваются с n
, но с формой они сильно различаются. - Ошибки сегментации происходят циклично!Выделение памяти для фигуры
(n,n,n)
на моей машине приближается к некоторому n
зависимому числу до sefault - но для n+1
мы снова в порядке.Кажется, что ~ 46k около 160 и ~ 56k около 224.
Нет хорошего объяснения от меня, но зависимость от n
заставляет меня думать, что распределения должны хорошо вписываться в какую-то битовую структуру, ииногда это ломается.
Я предполагаю, что использование 225
для ваших измерений будет работать - как обходной путь.