3
\$\begingroup\$

The problem is really simple: if I try to load with the function aiImportFileExWithProperties a big model in my software (around 200.000 vertices), it takes more than one minute. If I try to load the very same model with ASSIMP view, it takes 2 seconds.

For this comparison, both my software and Assimp view are using the dll version of the library at 64 bit, compiled by myself (Assimp64.dll).

This is the relevant piece of code in my software

// default pp steps
unsigned int ppsteps = aiProcess_CalcTangentSpace | // calculate tangents and bitangents if possible
    aiProcess_JoinIdenticalVertices    | // join identical vertices/ optimize indexing
    aiProcess_ValidateDataStructure    | // perform a full validation of the loader's output
    aiProcess_ImproveCacheLocality     | // improve the cache locality of the output vertices
    aiProcess_RemoveRedundantMaterials | // remove redundant materials
    aiProcess_FindDegenerates          | // remove degenerated polygons from the import
    aiProcess_FindInvalidData          | // detect invalid model data, such as invalid normal vectors
    aiProcess_GenUVCoords              | // convert spherical, cylindrical, box and planar mapping to proper UVs
    aiProcess_TransformUVCoords        | // preprocess UV transformations (scaling, translation ...)
    aiProcess_FindInstances            | // search for instanced meshes and remove them by references to one master
    aiProcess_LimitBoneWeights         | // limit bone weights to 4 per vertex
    aiProcess_OptimizeMeshes           | // join small meshes, if possible;
    aiProcess_SplitByBoneCount         | // split meshes with too many bones. Necessary for our (limited) hardware skinning shader
    0;

cout << "Loading " << pFile << "... ";

aiPropertyStore* props = aiCreatePropertyStore();

aiSetImportPropertyInteger(props,AI_CONFIG_IMPORT_TER_MAKE_UVS,1);
aiSetImportPropertyFloat(props,AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,80.f);
aiSetImportPropertyInteger(props,AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT);
aiSetImportPropertyInteger(props,AI_CONFIG_GLOB_MEASURE_TIME,1);
//aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);

// Call ASSIMPs C-API to load the file
scene = (aiScene*)aiImportFileExWithProperties(pFile.c_str(),
    ppsteps | /* default pp steps */
    aiProcess_GenSmoothNormals         | // generate smooth normal vectors if not existing
    aiProcess_SplitLargeMeshes         | // split large, unrenderable meshes into submeshes
    aiProcess_Triangulate              | // triangulate polygons with more than 3 edges
    //aiProcess_ConvertToLeftHanded    | // convert everything to D3D left handed space
    aiProcess_SortByPType              | // make 'clean' meshes which consist of a single typ of primitives
    0,
    NULL,
    props);

aiReleasePropertyStore(props);

if(!scene){
    cout << aiGetErrorString() << endl;
    return 0;
}

this is the relevant piece of code in assimp view code

// default pp steps
unsigned int ppsteps = aiProcess_CalcTangentSpace | // calculate tangents and bitangents if possible
        aiProcess_JoinIdenticalVertices    | // join identical vertices/ optimize indexing
        aiProcess_ValidateDataStructure    | // perform a full validation of the loader's output
        aiProcess_ImproveCacheLocality     | // improve the cache locality of the output vertices
        aiProcess_RemoveRedundantMaterials | // remove redundant materials
        aiProcess_FindDegenerates          | // remove degenerated polygons from the import
        aiProcess_FindInvalidData          | // detect invalid model data, such as invalid normal vectors
        aiProcess_GenUVCoords              | // convert spherical, cylindrical, box and planar mapping to proper UVs
        aiProcess_TransformUVCoords        | // preprocess UV transformations (scaling, translation ...)
        aiProcess_FindInstances            | // search for instanced meshes and remove them by references to one master
        aiProcess_LimitBoneWeights         | // limit bone weights to 4 per vertex
        aiProcess_OptimizeMeshes           | // join small meshes, if possible;
        aiProcess_SplitByBoneCount         | // split meshes with too many bones. Necessary for our (limited) hardware skinning shader
        0;

aiPropertyStore* props = aiCreatePropertyStore();
aiSetImportPropertyInteger(props,AI_CONFIG_IMPORT_TER_MAKE_UVS,1);
aiSetImportPropertyFloat(props,AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,g_smoothAngle);
aiSetImportPropertyInteger(props,AI_CONFIG_PP_SBP_REMOVE,nopointslines ? aiPrimitiveType_LINE | aiPrimitiveType_POINT : 0 );

aiSetImportPropertyInteger(props,AI_CONFIG_GLOB_MEASURE_TIME,1);
//aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);

// Call ASSIMPs C-API to load the file
g_pcAsset->pcScene = (aiScene*)aiImportFileExWithProperties(g_szFileName,

    ppsteps | /* configurable pp steps */
    aiProcess_GenSmoothNormals         | // generate smooth normal vectors if not existing
    aiProcess_SplitLargeMeshes         | // split large, unrenderable meshes into submeshes
    aiProcess_Triangulate              | // triangulate polygons with more than 3 edges
    aiProcess_ConvertToLeftHanded      | // convert everything to D3D left handed space
    aiProcess_SortByPType              | // make 'clean' meshes which consist of a single typ of primitives
    0,
    NULL,
    props);

aiReleasePropertyStore(props);

As you can see the code is nearly identical because I copied from assimp view.

What could be the reason for such a difference in performance? The two software are using the same dll Assimp64.dll (compiled in my computer with vc++ 2010 express) and the same function aiImportFileExWithProperties to load the model, so I assume that the actual code employed is the same.

How is it possible that the function aiImportFileExWithProperties is 100 times slower when called by my sotware than when called by assimp view?

What am I missing? I am not good with dll, dynamic and static libraries so I might be missing something obvious.

------------------------------

UPDATE

I found out the reason why the code is going slower. Basically I was running my software with "Start debugging" in VC++ 2010 Express. If I run the code outside VC++ 2010 I get same performance of assimp view.

However now I have a new question. Why does the dll perform slower in VC++ debugging? I compiled it in release mode without debugging information.

Is there any way to have the dll go fast in debugmode i.e. not debugging the dll? Because I am interested in debugging only my own code, not the dll that I assume is already working fine. I do not want to wait 2 minutes every time I want to load my software to debug.

Does this request make sense?

\$\endgroup\$
  • \$\begingroup\$ Have you tried profiling the code? \$\endgroup\$ – MichaelHouse Oct 13 '13 at 22:16
  • \$\begingroup\$ No I did not. The only thing that I am sure of is that my software gets stuck for more than 1 minutes on the function aiImportFileExWithProperties(), which is the ASSIMP function used to import the model from a file. Instead assimp view manages to display the model in around 2 seconds, which means that their call to aiImportFileExWithProperties() runs much faster. Are you suggesting to profile the dll? \$\endgroup\$ – Marco Oct 13 '13 at 22:21
  • \$\begingroup\$ Please don't update your question with an answer and a new question. Just post the answer and then mark it as accepted. Then post a new, separate question. (Your new question is much better suited to StackOverflow, though, since it's not game-specific.) \$\endgroup\$ – Sean Middleditch Dec 24 '13 at 1:39
4
\$\begingroup\$

Why does the dll perform slower in VC++ debugging? I compiled it in release mode without debugging information.

This is because windows use debug heap whenever you run your code from a debugger, note that this is different from CRT heap that is set in your project settings as Debug/Release.

In order to disable system heap debug you need to use _NO_DEBUG_HEAP=1 in your Windows environment settings, keep in my mind that such a huge difference in performance is caused by the library (Assimp) doing a huge number of allocations and de-allocations. For more info you can check this and this.

\$\endgroup\$
  • \$\begingroup\$ Unfortunately I tried both my dll and my software in release mode. I also set the _ITERATOR_DEBUG_LEVEL=0 in the release mode, just to be on the safe side. \$\endgroup\$ – Marco Oct 13 '13 at 22:16
  • \$\begingroup\$ have you tried setting less options for loading models ? maybe one or two options are causing the delay? \$\endgroup\$ – concept3d Oct 13 '13 at 22:25
  • \$\begingroup\$ Yeap, I tried this one as well. However, the options that you see I am loading are exactly the default options used by assimp view, so even if I use all of them, I should still perform the same as assimp view. \$\endgroup\$ – Marco Oct 13 '13 at 22:38
2
\$\begingroup\$

There can be multiple reasons for the Debug mode being slower.

One of the most likely ones(that affect performance the most) is that you are still linking with a dll that has Optimization off(you can still generate debug info, but make sure to turn Optimization on)

The second is because when debugging there is a special memory allocator used, that is somewhat slower, tough that shouldn't have such a high impact on performance, unless the application is extremely memory-intensive.

Edit: In my experience the algorithm that parses large sets of vertices and optimizes them for vertex locality is extremely memory intensive, so much, that it takes 20x longer in the debugger even in release builds.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.