2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 17:13 
Заслуженный участник


27/04/09
28128
Кстати, насколько понимаю, вопрос о RAM повис в воздухе, а ведь может быть ситуация, что кусок этого громадного массива лежит в свопе на диске. И не нужно говорить, насколько это плохо, если доступ далёк от последовательного.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 20:32 
Заслуженный участник


20/08/14
11867
Россия, Москва
Ну если уж "все счётчики поменял на int64", то стопудово проблема где-то в смешении типов, указатель и просто число (например счётчик цикла или промежуточный буфер для хранения указателя или параметр вызова функций или ещё какие-то вычисления над указателями). Причём она никуда не делась, так и осталась ненайденной.
Останов/замирание на 38Г может быть по другой причине, не именно из-за указателя, что-то другое где-то переполняется (и уходит в вечный цикл) или может и правда резко своп начинается, ничего ж не сказано. Но ведь не вылетает же - значит вряд ли дело в указателе в массив.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 21:18 


07/10/15

2400
Dmitriy40 в сообщении #1331680 писал(а):
... причём она никуда не делась, так и осталась ненайденной.
Останов/замирание на 38Г может быть по другой причине ...


Вот и я подозреваю, что где то осталась ошибка, буду пытаться найти (предыдущие копии у меня сохранились). По поводу 38Гб - сейчас ошибки нет, память загружается до 62 Гб без каких либо зависаний, вылечено сменой типов, причём в тех местах, где переменные, на первый взгляд уж ни как не должны принимать такие огромные значения. Вернусь назад и буду смотреть по новой, нудно понять, в чём было дело, это избавит от многих проблем в будущем.

Пока прошу подсказки

Используется синтаксис C
int a;
double *b;

................
double *str=(double*) malloc(a*b*sizeof(double));
 


какого тина результат будет в скобках malloс ?

насколько я понял, указатели 64 разрядные, т.к. с ними я ничего не делал и проблем сейчас нет,
но если я умножаю этот указатель на int то будет 64 разрядным результат, или он будет 32 разрядный, с возможным усечением?
Если второе, то может тогда как то явно указать тип произведения, например:
Используется синтаксис C
................................
double *str=(double*) malloc((_int64)(a*b*sizeof(double));
 


или от этого не будет толку, и нужно заводить переменную _int64, в ней всё сначала перемножить, а потом подставить в malloc() ?

-- 10.08.2018, 22:42 --

arseniiv в сообщении #1331647 писал(а):
Кстати, насколько понимаю, вопрос о RAM повис в воздухе, а ведь может быть ситуация, что кусок этого громадного массива лежит в свопе на диске. И не нужно говорить, насколько это плохо, если доступ далёк от последовательного.


тут вообще то речь идёт не о "лежании" а об обработке, будь он в swap, и без того медленная скорость стала бы просто неприемлемой ...

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 22:26 
Заслуженный участник


20/08/14
11867
Россия, Москва
Andrey_Kireew в сообщении #1331686 писал(а):
какого тина результат будет в скобках malloс ?
Я не понимаю, у Вас b - указатель на double. Но разве указатель можно умножать?! Мне помнилось для указателей определены лишь операции увеличения/уменьшения и взятия разности двух указателей (даже сумму указателей нельзя!), никаких умножений, делений, синусов, корней, логарифмов и прочего к ним применять нельзя. И тут компилятор должен был ругнуться и не компилить.
В чём собственно смысл умножения указателя на число?
Если у Вас весь код такого уровня ... :facepalm:
PS. Первый попавшийся пруф:
К указателям могут применяться только две арифметические операции: сложение и вычитание.
...
Можно добавлять или вычитать из указателей целые числа.
...
Помимо добавления или вычитания указателей и целых чисел, единственную операцию, которую можно выполнять с указателями, - это вычитание одного указателя из другого. В большинстве случаев вычитание одного указателя из другого имеет смысл только тогда, когда оба указателя указывают на один объект, - как правило, массив. В результате вычитания получается число элементов базового типа, находящихся между указателями. Помимо этих операций не существует других арифметических операций, применимых к указателям. Нельзя умножать или делить указатели, нельзя складывать указатели, нельзя применять битовый сдвиг или маски к указателям, нельзя добавлять или вычитать типы float или double.


-- 10.08.2018, 22:31 --

Может Вы путаете указатель и индекс в массиве (или и размер массива)? Это индекс можно и умножать, и делить, и что угодно делать, он как был числом так им и останется. А указатель - не число! И для него определены лишь строго ограниченные операции.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 23:20 


07/10/15

2400
Ну да, это я плохой пример придумал, такого конечно в коде нет и быть не должно,
вот конкретная, интересующая меня, строчка из кода:
Используется синтаксис C
size_t len_y;
int nVars;

................
double *str=(double*) malloc(nVars*len_y*sizeof(double));
 


int nVars я уже поменял на_int64 nVars, и вот думаю, могло это повлиять или нет?
результат sizeof() тоже size_t, а если умножить на int что получится? По идее должен получаться самый большой по размеру тип, но как оно на самом деле не знаю ...

-- 11.08.2018, 00:24 --

P.S.: на счёт умножения указателей я в курсе. Если умножать, то только их разности (ну или смещения). Сейчас посмотрел - они у меня раньше были типа int, а теперь уже _int64 может в этом проблема и была.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 23:35 
Заслуженный участник


20/08/14
11867
Россия, Москва
Неявное приведение типов всегда происходит к более точному, для целых - к знаковому большей разрядности. (Жаль что к знаковому, это создаёт проблемы, однако так.)
Используется синтаксис C
int a=1000000;
long int b=1000000000000;
int main(void)
{
    printf("%ld,%ld,%ld\n",a,b,a*b);
    return 0;
}
Вывод:
1000000,1000000000000,1000000000000000000
Использовался онлайн gcc. Как видно произведение реально 64-х битное.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение10.08.2018, 23:55 


07/10/15

2400
Тогда тут всё нормально. Но первую ошибку я выявил точно, дело было в смещении адресов, на больших данных оно вылезло за пределы int. Больше пока ничего не нашел, но видимо, должно быть смещение, которое переполняется при общем объёме данных 38 Гб.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 00:05 
Заслуженный участник


20/08/14
11867
Россия, Москва
Andrey_Kireew
Dmitriy40 в сообщении #1331680 писал(а):
Останов/замирание на 38Г может быть по другой причине, не именно из-за указателя, что-то другое где-то переполняется (и уходит в вечный цикл) или может и правда резко своп начинается, ничего ж не сказано. Но ведь не вылетает же - значит вряд ли дело в указателе в массив.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 00:29 


07/10/15

2400
Dmitriy40 да нет, Вы не правильно меня поняли, как раз тоже попытка доступа к неразрешенной области памяти, появляется такое же как и положено в этом случае сообщение и программа "висит. Это не вечный цикл.

P.S.: swap там отключен, так как необходимости в нём никакой нет, памяти вполне достаточно для всего что нужно

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 00:48 
Заслуженный участник


20/08/14
11867
Россия, Москва
А-а-а, да, понял неправильно.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 07:56 


01/11/17
42
Некоторые опции компилятора выдают предупреждения когда больший тип int64 неявно присваиваеться меньшему inr32. Попробуйте найти и пользовать ету опцию для вашего компилятора.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 08:19 


07/10/15

2400
dobrichev это было, я исправлял так
Используется синтаксис C
int val=a*Len;
 Warning: .......

int val=int(a*Len);
  Ok!
 


вот и результат такого игнорирования ...
Разумеется, после смены всех типов на _int64 никаких преобразований типов не требуется и предупреждений больше нет (ну разве что одно - сравнение знакового _int64 и без знакового size_t, вылечено как обычно _int64(x), но тут проблем быть не должно, да и сразу будет понятно где, если что)

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 10:37 


01/11/17
42
Andrey_Kireew в сообщении #1331721 писал(а):
dobrichev это было, я исправлял так
Используется синтаксис C
int val=int(a*Len);
 


Вот так делать нельзя. Передумайте и попытайтесь найти если кое-что из этих интервенции осталось. Может быть и в другой форме, например val=(int)x.
Ищите в коде sizeof(int), возможно и там что-то перепутано.

Майкрософт имеют непонятною политику ограничывать количество доступной памьяти по разному в разных под-версии ОС. Найдите какие ограничения для вашей версии.

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 10:55 


07/10/15

2400
dobrichev спасибо, эти штуки я уже проверил, вроде как не осталось ничего такого.
Что касается Win7 x64, то для prof и выше, все они поддерживают 192 ГБ (по крайней мере так пишут, проверять не довелось), так что для моего железа её более чем достаточно

 Профиль  
                  
 
 Re: ограничения на выделение памяти malloc()
Сообщение11.08.2018, 14:08 
Заслуженный участник


20/08/14
11867
Россия, Москва
Andrey_Kireew в сообщении #1331721 писал(а):
ну разве что одно - сравнение знакового _int64 и без знакового size_t, вылечено как обычно _int64(x)
Пока такой код работать будет. Пока size_t не стал больше int64_t (вдруг через несколько лет захотите запустить код на машине с 10 и более экзабайтами памяти? :mrgreen:) - а тогда получите снова аналогичную проблему с обрезанием чисел, т.е. этим Вы рассыпаете по коду грабли места возможных в будущем ошибок, причём труднее обнаруживаемых (это уже не указатели с вылетом по ошибке доступа, тут лишь допустимое обращение в массив будет по другому индексу или зацикливание программы).
Потому я бы при сравнении приводил в обратную сторону, int64_t к size_t. И добавил бы в самое начало программы нечто типа
Используется синтаксис C++
assert(sizeof(int64_t) <= sizeof(size_t));//Надо снова перепроверять все преобразования типов

Как действовать если памяти на машине от 9 до 18 экзабайтов (и вы собрались обрабатывать такие массивы) и потому размер size_t и int64_t совпадает (если и правда совпадёт, а не будет расширен до 128 битов), а вот диапазон значений нет ($10^{19}$ для size_t допустимо, а для int64_t нет) - я не уверен. Одним из выходов было бы использование везде где идёт итерация массивов типа uint64_t вместо int64_t, но это сдвигает проблему в другие участки кода и часто усложняет код из-за пропадания удобного трюка с отрицательным индексом как недопустимого, да ещё и разность индексов станет беззнаковой что может обрушить некоторые алгоритмы. Возможно стоит пользоваться приведением size_t к int64_t как Вы и сделали (с обязательным assert(sizeof(int64)>=sizeof(size_t)) в начале программы), но всегда проверять после выделения больших массивов (или перед циклом их обработки) их размер примерно так
Используется синтаксис C++
assert(sizeof(array) < INT64_MAX);//Слишком огромный массив!

В общем решение с приведением size_t к int64_t выглядит как временное пока работающее, но кардинально лучшего мне в голову не приходит.

UPD.
Да, и если Вы под size_t на самом деле имели в виду указатели, то всё становится ещё в разы хуже, т.к. указатели даже в уже реально существующих системах вполне могут не влезать в int64_t, пример нашёлся тут в единственном ответе.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group