Проблемы с производительностью при чтении файла с HD, который не соответствует выравниванию байтов - PullRequest
0 голосов
/ 29 сентября 2010

У меня есть формат файла (.STL, стереолитография, структура стандартная и не может быть изменена. Не путать со стандартной библиотекой шаблонов), в которой используется структура данных размером 50 байт.Чтение с жесткого диска напрямую приводит к неправильному считыванию данных, так как 50 байтов не кратны 4.

Из всей 50-байтовой структуры мне нужно только 36 из этих байтов.Метод, который я сейчас использую для извлечения данных, состоит в том, чтобы вручную сместить позицию чтения файла до точки, где начинается следующий набор данных, считать 36 байтов во временную переменную и затем вывести данные во временную переменную.в правильную позицию в массиве.

Вот фрагмент кода:

threePoints* output = new threePoints [numTriangles]; // create an array to hold the entire file
threePoints* temp = new threePoints [1]; // temp variable to pull data out of each "cell"

// extract each triangle individualy
for (int i = 0; i < numTriangles; i++)
{
    stlFile.seekg (96 + i * 50, ios::beg);  //read vertex data and put them into tempoary array
                                            // offset = 80 header + 4 #triangles + 12 normal vector
    stlFile.read(reinterpret_cast<char*>(temp), (36)); // read the next 36 data blocks into holder, 3 points * 3 axis * 4 bytes per float
    output[i] = temp[0]; // dump values in holder into proper array
}

Этот метод работает, но работает медленно.Как мне сделать это, чтобы сделать его быстрее и эффективнее?

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

Ответы [ 3 ]

6 голосов
/ 29 сентября 2010

Вместо того, чтобы выполнять кучу небольших операций поиска и чтения, выделите большой буфер (скажем, достаточно для 1000 структур) и прочитайте сразу несколько записей.(Затем выполните итерацию по этому буферу, копируя нужные вам 36-байтовые блоки).

0 голосов
/ 29 сентября 2010

У меня нет данных STL для тестирования, но как насчет этого? ...

#include <fstream>

#pragma pack(push, 1)

struct stl_hdr {
   unsigned int header[80];
   unsigned int triangle_cnt;
};

struct triangle {
   float norm;
   float v1;
   float v2;
   float v3;
   short attr_cnt;
};

#pragma pack(pop)

using namespace std;

int main(int argc, char* argv[]) {
   ifstream file(argv[1], ios::in | ios::binary);

   if (file.is_open()) {
      stl_hdr hdr;
      file.read((char*)&hdr, sizeof(hdr));

      triangle* tris = new triangle[hdr.triangle_cnt];

      file.read((char*)tris, hdr.triangle_cnt * sizeof(triangle));

      file.close();
   }

   return 0;
}

Я создал две структуры на основе описания в Википедии формата STL . Код выше делает то же самое предположение, что и ваш код ... количество атрибутов равно нулю. И я упустил обработку ошибок / очистку.

0 голосов
/ 29 сентября 2010

Скобка определения структуры с #pragma pack(1,push) и #pragma pack(pop).Это поддерживается большинством компиляторов.Тогда не следует добавлять автоматическое заполнение.

В руководстве GCC утверждается, что это функция совместимости с Microsoft, но она существует всегда ... вероятно, дольше, чем сам GCC.

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