Создание большой 1D матрицы, возвращающей выход 11 - PullRequest
1 голос
/ 19 мая 2019

Я написал некоторый код, который использует одномерный массив для представления матрицы.В настоящее время я тестирую большие входные размеры.

Когда я устанавливаю rows и cols на 50000, программа завершает работу с кодом 11.

Я много пытался распечатать.

double* create_matrix_1d(int n_rows, int n_cols) {
    long long len = (long long ) n_rows * (long long) n_cols;

    auto* A = new double[len];

    int row, col ;

    for(row = 0; row < n_rows; row++) {
        for( col = 0; col < n_cols; col++) {
            int i = col + row * n_cols;

            A[i] = 1; //static_cast <int> (rand()) % 10 ;
        }
    }

    return A;
}

Ответы [ 3 ]

1 голос
/ 19 мая 2019

Давайте вычислим необходимую память.Двойной тип обычно использует 8 байтов, поэтому ваша матрица требует:

50000*50000*8 = 20000000000 bytes

памяти

20000000000 bytes = 20000000000 / 1024 = 19531250 kb

19531250 / 1024 = 19073 Mb

19073  / 1024 = 18.6265 Gb

Так что, если у вас нет компьютера с более чем 19 ГБ ОЗУ, это нормально, что вывывести из памяти ошибку

0 голосов
/ 19 мая 2019

На этот вопрос уже ответил Винсент.

Я просто оставляю несколько комментариев по поводу написанного кода:

  • Всегда безопаснее использовать RAII использование структур данных stdlib, таких как vector, должно помочь
  • Также вложенные циклы могли бы быть записаны как -
for(int i=0; i<nrows*ncols; ++i)
  A[i] = 1.0;

Помогает компилятору действовать немного умнее при отображении векторизованные инструкции .

Удачного кодирования!

0 голосов
/ 19 мая 2019

ответ должен быть легким.Но я не могу быть уверен, потому что вы дали недостаточно информации о вашем компиляторе, языке и вашем оборудовании.И самое главное, я не вижу вопроса.

Но мы предполагаем, что вы хотите знать, почему ваша рутина терпит неудачу.

Далее.Я не был уверен, какой язык вы используете.Это похоже на обычный старый C, но по какой-то причине вы использовали ключевое слово auto и static_cast в комментарии.Итак, это «должен» быть C ++.

Сначала ответ, затем несколько дополнительных комментариев:

Вы пытаетесь выделить 19 ГБ в куче.В зависимости от используемой вами модели памяти и наличия физической памяти, это может произойти сбой.

Кроме того, вы пишете

int i = col + row * n_cols;

Это создаст переполнение.

Второе: некоторые предложения по улучшению.

Если вы используете современный C ++, вам следует использовать современный C ++.Звучит странно, но ваш код выполнен в стиле C.

Если вы действительно хотите обрабатывать большие данные, вы можете рассмотреть базу данных.Но я сомневаюсь, что вам действительно нужно 19 ГБ заполненных данных.Существуют и другие методы хранения только необходимых данных.Вы должны изменить свой алгоритм.

Я прокомментировал ваш код, чтобы дать хотя бы несколько предложений по улучшению:

// Rows and Cols could be made const. They are not modified in your code
// If you anyway later cast to long long, then you could also make the parameters long long
// You should use unique_ptr to take ownership of the allocated memory
// But this cannot be copied and needs to be "moved" out of the function
// You should use a C++ container to hold your matrix, like a std::vector
double* create_matrix_1d(int n_rows, int n_cols) {
    // You should not use C-Style Cast but static_cast
    long long len = (long long ) n_rows * (long long) n_cols;
    // You should use a unique_ptr to handle the resource
    auto* A = new double[len];

    int row, col ;

    for(row = 0; row < n_rows; row++) {
        for( col = 0; col < n_cols; col++) {
            // The "int i" can most likely hold only (2^32-1)
            // SO you will get an overfolow here
            int i = col + row * n_cols;
            // You wanted to assign an int to a double
            A[i] = 1; //static_cast <int> (rand()) % 10 ;
        }
    }

    return A;
}

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...