2015-10-11 4 views
-3

У меня есть файл данных 36 МБ (каждое значение в файле двойного типа), находящееся на жестком диске. Мой вопрос в том, что когда я читаю этот файл через C++ в ОЗУ, помещая контент в матрицу (предоставляемый библиотекой boost), он будет занимать только 36 МБ ОЗУ или другой? У меня заканчивается память?Разница в размере файла на жестком диске и оперативной памяти

Причина в том, что я на 64-битной платформе ubuntu с 8 ГБ оперативной памяти, и я получаю плохую ошибку размещения. Одна и та же программа чтения файлов отлично подходит для небольших файлов данных.

Ниже приведен фрагмент для загрузки (данные real-sim) [https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary.html]. x и y - форматированная матрица и вектор, объявленные как extern в .h файле.

void load_data(const char* filename) 
{ 
    ifstream in(filename); 
    string line; 
    int line_num = 0; 
    if (in.is_open()) { 
     while (in.good()) { 
      getline(in, line); 
      if (line.empty()) continue; 
      int cat = 0; 
      if (!parse_line(line, cat, line_num)) { 
       cout << "parse line: " << line << ", failed.." << endl; 
       continue; 
      } 

      y(line_num) = cat; 

      line_num += 1; 
     } 
     in.close(); 
    } 
} 

bool debug = false; 
using namespace boost::numeric::ublas; 
vector<double> y(no_records); 
matrix<double> x(no_records,no_features); 
using namespace std; 

template < class T> 
void convert_from_string(T& value, const string& s) 
{ 
stringstream ss(s); 
ss >> value; 
} 

int get_cat(const string& data) { 
int c; 
convert_from_string(c, data); 

return c; 
} 


bool get_features(const string& data, int& index, double& value) { 
int pos = data.find(":"); 
if (pos == -1) return false; 
convert_from_string(index, data.substr(0, pos)); 
convert_from_string(value, data.substr(pos + 1)); 

return true; 
} 


bool parse_line(const string& line, int& cat, const int line_num) { 
if (line.empty()) return false; 
size_t start_pos = 0; 
char space = ' '; 

while (true) { 
    size_t pos = line.find(space, start_pos); 

    if ((int)pos != -1) { 
     string data = line.substr(start_pos, pos - start_pos); 
     if (!data.empty()) { 
      if (start_pos == 0) { 
       cat = get_cat(data); 
      } 
      else { 
       int index = -1; 
       double v = 0; 
       get_features(data, index, v); 
       if (debug) 
        cout << "index: " << index << "," << "value: " << v << endl; 
       if (index != -1) { 
        index -= 1; // index from 0 
        x(line_num, index) = v; 
       } 
      } 
     } 
     start_pos = pos + 1; 
    } 
    else { 
     string data = line.substr(start_pos, pos - start_pos); 
     if (!data.empty()) { 
      cout << "read data: " << data << endl; 
      int index = -1; 
      double v = 0; 
      get_features(data, index, v); 
      if (debug) 
       cout << "index: " << index << "," << "value: " << v << endl; 
      if (index != -1) { 
       index -= 1; // index from 0 
       x(line_num, index) = v; 
      } 
     } 
     break; 
    } 
} 

return true; 
} 
+3

Он будет занимать примерно столько же да. Сбой/исключение, которое вы получаете * может * быть связано с размером, но это не обязательно, но невозможно сказать что-либо без дополнительной информации, предпочтительно кода. Попробуйте создать [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve) и покажите нам вместе с небольшой выборкой входного файла (если это текст). –

+3

Вы сделали предположение, что почти наверняка будет недействительным. 36MB ничего, и размер файла не является прямым источником ваших ошибок. –

+0

Я только что запустил свою программу в файле (42 МБ на hdd), который содержит 1000 строк и 5K столбцов (функции). Он прошел отлично. Но когда я попытался запустить тот же код с файлом данных, содержащим строки 70K и 20K столбцов, возникла ошибка с плохим распределением (также в файле данных размером 10K X 1M). Это означает, что размер файла не задается. Но, можете ли вы догадаться, почему эта ошибка происходит? – chandresh

ответ

0

Я нашел преступника. Причиной ошибки bad allocation было то, что у меня не хватало памяти. Дело в том, что я использовал dense matrix представление (предоставленное библиотекой boost). Таким образом, сохранение матрицы размера 20000x40000 в качестве плотной матрицы в представлении с расширенной матрицей потребует ОЗУ размером 6.4GB. Теперь, если у вас не так много места в ОЗУ, будет всплывать плохое распределение.

Смежные вопросы