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
12082
Россия, Москва
Ну если уж "все счётчики поменял на 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
12082
Россия, Москва
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
12082
Россия, Москва
Неявное приведение типов всегда происходит к более точному, для целых - к знаковому большей разрядности. (Жаль что к знаковому, это создаёт проблемы, однако так.)
Используется синтаксис 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
12082
Россия, Москва
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
12082
Россия, Москва
А-а-а, да, понял неправильно.

 Профиль  
                  
 
 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
12082
Россия, Москва
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, Супермодераторы



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

Сейчас этот форум просматривают: Bing [bot]


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

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