Search code examples
c++openmp

Parallizing loading from a model in file


I have a model mesh that I want to load its vertices, indices, in parallel. The problem is I had to remove return statements if eof is catched for each block, reading vertices, reading faces. also I'm not sure if that's correct approach. MVP Code is here.

    std::ifstream inp(file_name, std::ios::in | std::ios::binary);
        char buffer[40] = { 0 };
            if (inp.eof()) {
                return false;
            }
            inp.read(buffer, 40);
// making sure it is little endian
            auto ReadUnsignedIntLittleEndian = [&]() {
                unsigned int num = 0;
                for (int i = 0; i < 4; ++i) {
                    if (inp.eof()) {
                        throw - 1; // throw and exception
                    }
                    inp.read(buffer, 1);
                    unsigned int tmp = (unsigned char)(buffer[0]);
                    tmp <<= (i * 8);
                    num = num | tmp;
                }
                return num;
            };
                auto ReadReal = [&]() {
                inp.read(buffer, sizeof(T));
                T num = *((T*)&(buffer[0]));
                return num;
            };
        // read vertices
            #pragma omp for
            for (int i = 0; i < numVerts; ++i)
            {
                T x = ReadReal();
                //if(inp.eof()) return;
                T y = ReadReal();
               //if(inp.eof()) return;
                T z = ReadReal();
                //if(inp.eof()) return;
                meshPtr->AddVertex(x, y, z);
            }
    
            // read edges
            #pragma omp for
            for (int i = 0; i < numEdges; ++i) {
                int v1 = ReadUnsignedIntLittleEndian();
                int v2 = ReadUnsignedIntLittleEndian();
                meshPtr->AddEdge(v1, v2);
            }
    }

Here is how Add Vertex looks like:

int Mesh<T>AddVertex(const Vertex<T> vertex)
{
    int vertexIndex = vertices_.size();
    auto v = std::make_shared<Vertex<T> >(vertex);
    v->SetIndex(vertexIndex);
    vertices_.push_back(v);
    return vertexIndex;
}

Solution

  • To load data fast, make your class structure exactly match the file format.

    If the file contains repeated binary data:

    float
    float
    float
    int
    

    then your vertex class should be

    class Vertex {
        float x, y, z;
        int index;
    };
    

    and reading it will be as easy as this

    Vertex *data = new Vertex[numVerts];
    fread(data, sizeof(Vertex), numVerts, file);