Узкое место ОЗУ при загрузке - можно ли оптимизировать код? - PullRequest
1 голос
/ 14 мая 2019

У меня 1000 пациентов.Для каждого пациента я предварительно рассчитал (100x100x1000) сетку, то есть примерно 10 миллионов точек данных.По сути, мне нужно взять первую точку данных (первый индекс) каждой сетки пациентов и суммировать их, а затем вторую и т. Д. Так что просто суммируйте каждую точку данных для всей сетки всех пациентов.В принципе это должно вернуть одну (100x100x1000) сетку со всеми суммированными значениями от всех пациентов.

Однако моя проблема заключается в том, что каждая предварительно рассчитанная сетка составляет примерно 35 МБ.Таким образом, с тысячами из них, это где-то около 35 ГБ оперативной памяти, необходимой для хранения всего этого в памяти, которого у меня сейчас нет.

Итак, что я делаю сейчас, так это перезагружаю одну сетку за раз, изатем «сохранение» суммы для каждого, так что у меня есть только два открытых одновременно (так сказать).Я делаю это с:

patients = np.linspace(0, 1000, 1000)

def sum_iter(values, index_list):
    sum_ = np.zeros((100, 100, 1000), dtype=int)
    generator_index = -1

    for index in index_list:
        try:
            while generator_index < index:
                vector = next(values)
                generator_index = generator_index + 1
            sum_ = (sum_ + vector)
        except StopIteration:
            print("Done")

    return sum_

for t in range(1, 1000):
    print("Bootstrap sequence: {}".format(t))

    ### random sampling with replacement ###
    patients_boot = np.random.choice(patients, size=patients.shape, replace=True)  

    log_values = (np.load("data/{}/grid.npy".format(patient)) for patient in patients)

    log_likely_final = sum_iter(log_values, patients)

... и затем что-то происходит после последней строки кода, но это быстро, и я думаю, что в данном случае это не имеет значения.

Так что это работает.Однако, если сетки такие большие, как сейчас, это займет некоторое время.Примерно 1-2 минуты для каждой итерации.Но я также хочу сделать некоторую загрузку, которая указана в коде.Но, как вы можете себе представить, делая 1000 повторных сэмплов, ну, тогда это 1000-2000 мин, что довольно долго.

Я понятия не имею, можно ли это каким-то образом оптимизировать, поэтому расчетвремя не так плохо.На данный момент каждая отдельная сетка перезагружается каждый раз по одному для каждой повторной выборки.Может быть, кто-то может сделать это так, чтобы я загружал x-количество сеток до тех пор, пока моя RAM не была заполнена (или близка к ней), использую это, сохраняю ее, а затем повторно загружаю следующие x-числа, пока RAM снова не заполняется и так далее.

...