1
\$\begingroup\$

I am new user for GLM, can somebody guide me how to use GLM SIMD using its version 0.9.8.2.

According to its Manual using #define GLM_FORCE_SSE2

For example, if I write:

#define GLM_FORCE_SSE2

#ifdef GLM_FORCE_SSE2

glm::vec3 v(1.0f);

#endif

I am unable to notice any difference if I write this now:

glm::vec3 v(1.0f);

unlike older version of GLM where I can use different function like

#include <GLM\GTX\simd_mat4.hpp>
glm::detail::fvec4SIMD v(1.0f); //for simd 
glm::vec3 v(1.0f); //for non simd

but with version 0.9.8.2 I am confused.

\$\endgroup\$
1
\$\begingroup\$

The good news is that simd support is now part of the standard GLM types (GLM\GTX\simd_mat4.hpp is deprecated), the bad news is that its activation looks broken. Here is how I managed to enable the use of simd intrinsics in GLM.

First, before any inclusion of a glm header, define:

#define GLM_FORCE_SSE2 // or GLM_FORCE_SSE42 if your processor supports it
#define GLM_FORCE_ALIGNED

And then in glm/detail/precision.hpp, replace the following lines:

highp = packed_highp,
mediump = packed_mediump,
lowp = packed_lowp,

By

highp = aligned_highp,
mediump = aligned_mediump,
lowp = aligned_lowp,
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you Yvain, I had no idea about it, because glm manuals are bit confusing, in this regard. They should have clearly mentioned or given some examples. \$\endgroup\$ – Aiman Shaikh Nov 29 '16 at 18:04
1
\$\begingroup\$

It also depends on your OS and compiler. I'm testing GLM-0.99, and this is the behavior I observe. Note that I have the following macros defined before including glm headers:

#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
#define GLM_FORCE_SIMD_AVX2
  • On MacOS 10.14 with clang++ compiler, I get executable with SIMD right away.
  • On Ubuntu 16.04 with g++ compiler, I will have to use the compiler flag -mavx2 to generate a SIMD executable. There are other compiler options for other SIMD instructions here. Without the compiler flag, I still get a serial executable.

P.S. I used the following test program to time the executable and know if it's SIMD enabled. Without SIMD, it takes ~12s, and with SIMD, it's ~2s (on a Core i7 processor).

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <sys/time.h>

#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
#define GLM_FORCE_SIMD_AVX2
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#define NUM_VERT 1000000000
#define PI 3.14159f

int main()
{

    float* buf = new float[ NUM_VERT + 4 ];

    std::srand( std::time(nullptr) );
    for( size_t i = 0; i < NUM_VERT + 4; i++ )
        buf[i] = float(std::rand() % 100) * PI;

    glm::mat4 Model = glm::translate( glm::mat4(1.0f), glm::vec3(1.0f));
    Model[3][2] = 0.11f;
    Model[2][0] = -0.1f;
    Model[0][1] = 0.04f;
    Model[1][3] = -0.2f;

    double sum = 0.0;
    struct timeval start, finish;
    glm::vec4 Pos, Trans;
    gettimeofday( &start, NULL );

    for( size_t i = 0; i < NUM_VERT; i++ )
    {
        Pos.x = buf[ i ];
        Pos.y = buf[ i + 1 ];
        Pos.z = buf[ i + 2 ];
        Pos.w = buf[ i + 3 ];
        Trans = Model * Pos;
        sum += glm::length( Trans );
    }

    gettimeofday( &finish, NULL );
    double sec = (finish.tv_sec - start.tv_sec) + ((finish.tv_usec - start.tv_usec)/1000000.0);
    std::cout << "total time = " << sec << std::endl;
    std::cout << "  sum = " << sum << std::endl;

    delete[] buf;

    return 0;
}
| improve this answer | |
\$\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.