2
\$\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\$

2 Answers 2

2
\$\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,
\$\endgroup\$
1
  • \$\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\$ Commented Nov 29, 2016 at 18:04
3
\$\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;
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .