Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> нехватка оперативной памяти ? 
:(
    Опции темы
Remiznik
Дата 30.7.2009, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



Нужно загрузить очень большой фале в ОП но её может не хватить как сделать чтоб программа не падала от нехватки ОП ?

У меня есть две идеи но как их реализовать не знаю !
1. Начать закружать ОП и если она кончиться то перехватить это исключение и обработать  его. 
2. Каким-то обзором определить количество свободной ОП до начала загрузки файла и уже там думать что с этим делать.

По 1 не знаю какое исключение генерируется и как его отловить. 
По 2 не знаю как определить кол-во свободной ОП.

Посоветуйте что делать, или может есть ешо какие идеи для предотвращения паления программы ! 
PM MAIL   Вверх
Sartorius
Дата 30.7.2009, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: нет
Всего: 37



А вы про виртуальную память слышали? До вас уже обо всем позаботились...

ЗЫ Что то мне подсказывает, что вашу задачу можно решить без загрузки в память всего файла.

Это сообщение отредактировал(а) Sartorius - 30.7.2009, 14:41
PM MAIL ICQ   Вверх
azesmcar
Дата 30.7.2009, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 1
Всего: 211



Remiznik

Используй функцию mmap.
PM   Вверх
Cheloveck
Дата 30.7.2009, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: нет
Всего: 32



Цитата(Sartorius @  30.7.2009,  15:39 Найти цитируемый пост)
ЗЫ Что то мне подсказывает, что вашу задачу можно решить без загрузки в память всего файла.


Sartorius мне подсказывает, что то, что мне что-то подсказывает, что вашу задачу можно решить без загрузки всего файла в ОП, правильно. Я, вот сейчас работаю с файлами 100+ Mb и использую потоки.


--------------------
user posted image
PM Jabber   Вверх
Remiznik
Дата 1.8.2009, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



azesmcar, спасибо за ссылку но както пока не разобрался как использовать эту функцию ... примера нет а по описанию мне както не вникнуть что она делает .

Cheloveck а можно поподробнее по потоки , как ты их используешь чтоб не загружать весь в фаел в ОП ?
PM MAIL   Вверх
azesmcar
Дата 1.8.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 1
Всего: 211



Цитата(Remiznik @  1.8.2009,  15:07 Найти цитируемый пост)
azesmcar, спасибо за ссылку но както пока не разобрался как использовать эту функцию ... примера нет а по описанию мне както не вникнуть что она делает .

Что, примеров не нашел?
http://www.cs.purdue.edu/homes/fahmy/cs503/mmap.txt
http://www.linuxquestions.org/questions/pr...rial-cc-511265/
http://www.devshed.com/c/a/BrainDump/Using...vanced-File-IO/
http://publib.boulder.ibm.com/infocenter/i...=/apis/mmap.htm
http://www.ecst.csuchico.edu/~beej/guide/ipc/mmap.html

Добавлено через 57 секунд
Цитата(Remiznik @  1.8.2009,  15:07 Найти цитируемый пост)
что она делает

Написано же
Цитата

The mmap() function asks to map length bytes starting at offset offset from the file (or other object) specified by the file descriptor fd into memory

http://www.translate.ru
PM   Вверх
Remiznik
Дата 1.8.2009, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



то есть в функцию передаём файл и она проверяет поместится он в ОП или нет ?


PM MAIL   Вверх
azesmcar
Дата 1.8.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 1
Всего: 211



Цитата(Remiznik @  1.8.2009,  15:52 Найти цитируемый пост)
то есть в функцию передаём файл и она проверяет поместится он в ОП или нет ?

нет, проецирует файл в память.
PM   Вверх
Cheloveck
Дата 2.8.2009, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: нет
Всего: 32



Цитата(Remiznik @  1.8.2009,  16:07 Найти цитируемый пост)

Cheloveck а можно поподробнее по потоки , как ты их используешь чтоб не загружать весь в фаел в ОП ? 

Код


// Копирует всё содержимое input в output.
void copy_stream( std::ifstream & input, std::ofstream & output )
{
    if( !input.is_open() || input.eof() || !output.is_open() )
        return;

    std::string str;
    while( !input.eof() && std::getline( input, str ) )
    {
        output << str << std::endl;
    }
}

Вот кусок из одной из моих прог.


--------------------
user posted image
PM Jabber   Вверх
andrew_121
Дата 2.8.2009, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Cheloveck, Что-то я не вижу чтоб было указанно что данные только текстовые.

Добавлено через 6 минут и 26 секунд
Remiznik, Так задача собственно какая? Скопировать файл?
Если да, то тут:
http://forum.vingrad.ru/forum/topic-267913.html


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
LisAnd
Дата 3.8.2009, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 13.5.2009

Репутация: нет
Всего: нет



Отображаемая память рулитsmile
PM MAIL   Вверх
Remiznik
Дата 3.8.2009, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



задача в том что есть файл там данные записаны особенным обзором и их не просто нужно загрузить в память а в вектор но прежде чем загрузить в вектор нужно выделить под него память а если файл слишком большой выдать предупреждении !

Код

 struct mystruct
{
    int param1;
    int param2;
}

vector<mystruct> Data;

int size;           // количество данных 
Data.resize(size);


и мне нужно знать хватит ли места в ОП для этого вектора.
PM MAIL   Вверх
vinick
Дата 3.8.2009, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 4
Всего: 22



Цитата(Remiznik @  3.8.2009,  21:19 Найти цитируемый пост)
и мне нужно знать хватит ли места в ОП для этого вектора. 

Можешь попробовать ловить std::bad_alloc из resize и SIGSEGV. resize вызывает констурторы для элементов, следовательно доступ к памяти будет, а значит либо исключение, либо сигнал выстрелят.

 Но лучше пересмотреть алгоритм. Что ты будешь делать если файл попадется такой, что со скрипом влезет в память, но ни на что другое памяти уже не останется? А что делать пользователю с твоим предупреждением? бежать в магазин за планкой памяти, за двумя или заказывать кластер на петабайт?
PM MAIL ICQ Jabber   Вверх
Remiznik
Дата 3.8.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



да я понимаю что все данные загружать в ОП это абсурд ... но если файл не помешается в ОП то я применю алгоритм и буду выборочно загружать .... но если файл помешается то надо загрузить !
PM MAIL   Вверх
andrew_121
Дата 3.8.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Напиши свой объект вектор. В нем, вместо выделения памяти, используй проецирование файла в память.
Какие именно операции ты выполняешь с этим вектором?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Remiznik
Дата 3.8.2009, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



просто я использую эти данные для дальнейшей обработки ....можно конечно напрямую данные брать из файла на диске но это при большом количестве обращений к файлу очень влияет на время работы.
PM MAIL   Вверх
andrew_121
Дата 3.8.2009, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Remiznik, Ты не понял.

Цитата(andrew_121 @  3.8.2009,  22:27 Найти цитируемый пост)
Какие именно операции ты выполняешь с этим вектором? 

Т.е. Какие методы вектора, содержащего данные из этого файла, тебе нужны?

Пример:
Код

struct mystruct {
    int param1;
    int param2;
};


template<typename T> class MyVector {
public:
    MyVector(const std::string& filename) {
        ...
        uint filesize = ...;
        int fd = open(filename, ...);
        
        _ptr = mmap(..., fd, ...); /* <<<<<<<<<<<<<<<<<<<<<<<< */
        
        _count = filesize / sizeof(T);
    }
    const T& operator[] (int idx) const {
        if ( idx <= _count ) {
            return *(const T*)_ptr+idx*sizeof(T);
        }
        return T(); /* что-то типа этого или исключение*/
    }
protected:
    uint _count;
    char* _ptr;
};

int main(int argc, const char **argv) {
    MyVector<mystruct> vec("./file.dat");
    return 0;
}


Вот. Реализуй необходимые тебе методы.

Добавлено @ 22:52
Я показал пример реализации вектора с перегруженным оператором индексирования.

Это сообщение отредактировал(а) andrew_121 - 4.8.2009, 11:15


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Remiznik
Дата 3.8.2009, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 30.4.2005

Репутация: нет
Всего: 1



да только функцию воврашения значения по индексу который мне нужен. Просто вектор использую в место массива мне так удобнее.
PM MAIL   Вверх
andrew_121
Дата 3.8.2009, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Remiznik, Ну вот тебе каркас вектора использующего проецирование файла в память. Допиши и используй на здоровье.

Добавлено через 9 минут и 41 секунду
Щас поэкспериментирую, любопытно smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
andrew_121
Дата 4.8.2009, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



В общем вот что получилось.
Код

#include <io.h>
#include <fcntl.h>

#include <string>
#include <cassert>
#include <iostream>
#include <fstream>
#include <exception>

#ifdef WIN32
#  include "glibc/mman.h"
#else
#  include <sys/mman.h>
#endif

class bad_index : public std::exception {
public:
    bad_index() throw() : std::exception() {}
    virtual ~bad_index() {}
};

class not_init : public std::exception {
public:
    not_init() throw() : std::exception() {}
    virtual ~not_init() {}
};

template<typename T> class MyVector {
public:
    MyVector(const std::string& fn):_fd(-1), _fs(0), _count(0), _fn(fn), _ptr(NULL) {}
    virtual ~MyVector() {}
    /*  */
    bool good() const { return _fd != -1; }
    int count() const {
        if ( _fd < 0 ) {
            throw not_init();
        }
        return _count;
    }
    /*  */
    bool init() {
        _fd = open(_fn.c_str(), _O_BINARY|_O_RDONLY);
        if ( _fd < 0 ) return false;
        
        lseek(_fd, 0L, SEEK_END);
        _fs = tell(_fd);
        lseek(_fd, 0L, SEEK_SET);
        
        _count = _fs/sizeof(T);
        
        _ptr = (char*)mmap(NULL, _fs, PROT_READ, MAP_PRIVATE, _fd, 0);
        return _ptr != NULL;
    }
    void free() {
        if ( _ptr ) {
            munmap(_ptr, _fs);
            _ptr = NULL;
        }
        if ( _fd > 0 ) {
            close(_fd);
            _fd = -1;
        }
    }
    const T& operator[] (int idx) const {
        if ( idx < 0 || idx > _count ) {
            throw bad_index();
        }
        return *(const T*)(_ptr+idx*sizeof(T));
    }
protected:
    int _fd;
    int _fs;
    int _count;
    std::string _fn;
    char* _ptr;
};

struct mystruct {
    int param1;
    int param2;
};

void create_file(const std::string& fn, int count) {
    std::ofstream file(fn.c_str(), std::ios::binary);
    if ( !file.good() ) return;
    
    mystruct data;
    while ( count-- ) {
        data.param1 = data.param2 = rand();
        
        file.write((const char*)&data, sizeof(data));
    }
    
    file.close();
}

int main(int argc, const char **argv) {

    const int count = 1024*1024*100;
    const std::string filename("data.dat");
    create_file(filename, count);

    MyVector<mystruct> vec(filename);
    mystruct data;
    
    assert(vec.init());
    
    try {
        int cnt = vec.count();
        assert(cnt == count);
        int idx = 0;
    
        while ( cnt-- ) {
            data = vec[idx++];
        }
    }
    catch ( const bad_index& e ) {
        std::cout << "bad_index" << std::endl;
    }
    catch ( const not_init& e ) {
        std::cout << "not_init" << std::endl;
    }
    catch ( ... ) {
        std::cout << "who?" << std::endl;
    }
    vec.free();
    
    return 0;
}

Странное поведение под виндавз. Съедает всю память, даже отбирает ее у запущенных программ/процессов. В Linux, все в порядке. Выделяет не больше чем свободной памяти есть. Процессы не обделяет.

Это сообщение отредактировал(а) andrew_121 - 4.8.2009, 21:17


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
MAKCim
Дата 5.8.2009, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(Remiznik @  3.8.2009,  22:35 Найти цитируемый пост)
можно конечно напрямую данные брать из файла на диске но это при большом количестве обращений к файлу очень влияет на время работы. 

1. fread/fwrite используют кэш
2. mmap работает так же как и fread за исключением того, что чтение происходит неявным образом
+readahead, который, к слову реализуется и через fread

Добавлено через 1 секунду
Цитата(Remiznik @  3.8.2009,  22:35 Найти цитируемый пост)
можно конечно напрямую данные брать из файла на диске но это при большом количестве обращений к файлу очень влияет на время работы. 

1. fread/fwrite используют кэш
2. mmap работает так же как и fread за исключением того, что чтение происходит неявным образом
+readahead, который, к слову реализуется и через fread




--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
andrew_121
Дата 5.8.2009, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Цитата(MAKCim @  5.8.2009,  19:43 Найти цитируемый пост)
1. fread/fwrite используют кэш

Да.
Но если учесть что нужен произвольный доступ, не думаю что кэш будет работать при большом объеме файла.


Цитата(MAKCim @  5.8.2009,  19:43 Найти цитируемый пост)
readahead

Не знал что есть такое. smile  Спасибо!


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
MAKCim
Дата 6.8.2009, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(andrew_121 @  5.8.2009,  21:46 Найти цитируемый пост)
не думаю что кэш будет работать при большом объеме файла.

setvbuf


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
andrew_121
Дата 6.8.2009, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



Цитата(MAKCim @  6.8.2009,  20:39 Найти цитируемый пост)
setvbuf 

Нужно экспериментировать.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.1358 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.