From 00d1c2a000216184893b59166c09927d2fd4deba Mon Sep 17 00:00:00 2001 From: HOSOKAWA Kenchi Date: Sat, 4 Apr 2015 09:31:44 +0900 Subject: [PATCH] VC12 --- psychlops/core/math/dSFMT2.0/dSFMT-common.h | 115 +++++++++++++++++ psychlops/core/math/dSFMT2.0/dSFMT-params.h | 12 +- psychlops/core/math/dSFMT2.0/dSFMT-params19937.h | 4 +- psychlops/core/math/dSFMT2.0/dSFMT.c | 157 +++++------------------ psychlops/core/math/dSFMT2.0/dSFMT.h | 100 +++++++++------ win32gl/dev/psychlopswin32.cbp | 6 +- win32gl/test/Psychlops_win32cblibtest.cbp | 2 +- 7 files changed, 222 insertions(+), 174 deletions(-) create mode 100644 psychlops/core/math/dSFMT2.0/dSFMT-common.h diff --git a/psychlops/core/math/dSFMT2.0/dSFMT-common.h b/psychlops/core/math/dSFMT2.0/dSFMT-common.h new file mode 100644 index 0000000..30c26c0 --- /dev/null +++ b/psychlops/core/math/dSFMT2.0/dSFMT-common.h @@ -0,0 +1,115 @@ +#pragma once +/** + * @file dSFMT-common.h + * + * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom + * number generator with jump function. This file includes common functions + * used in random number generation and jump. + * + * @author Mutsuo Saito (Hiroshima University) + * @author Makoto Matsumoto (The University of Tokyo) + * + * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. + * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima + * University and The University of Tokyo. + * All rights reserved. + * + * The 3-clause BSD License is applied to this software, see + * LICENSE.txt + */ +#ifndef DSFMT_COMMON_H +#define DSFMT_COMMON_H + +#include "dSFMT.h" + +#if defined(HAVE_SSE2) +# include +union X128I_T { + uint64_t u[2]; + __m128i i128; +}; +union X128D_T { + double d[2]; + __m128d d128; +}; +/** mask data for sse2 */ +static const union X128I_T sse2_param_mask = {{DSFMT_MSK1, DSFMT_MSK2}}; +#endif + +#if defined(HAVE_ALTIVEC) +inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b, + w128_t *lung) { + const vector unsigned char sl1 = ALTI_SL1; + const vector unsigned char sl1_perm = ALTI_SL1_PERM; + const vector unsigned int sl1_msk = ALTI_SL1_MSK; + const vector unsigned char sr1 = ALTI_SR; + const vector unsigned char sr1_perm = ALTI_SR_PERM; + const vector unsigned int sr1_msk = ALTI_SR_MSK; + const vector unsigned char perm = ALTI_PERM; + const vector unsigned int msk1 = ALTI_MSK; + vector unsigned int w, x, y, z; + + z = a->s; + w = lung->s; + x = vec_perm(w, (vector unsigned int)perm, perm); + y = vec_perm(z, (vector unsigned int)sl1_perm, sl1_perm); + y = vec_sll(y, sl1); + y = vec_and(y, sl1_msk); + w = vec_xor(x, b->s); + w = vec_xor(w, y); + x = vec_perm(w, (vector unsigned int)sr1_perm, sr1_perm); + x = vec_srl(x, sr1); + x = vec_and(x, sr1_msk); + y = vec_and(w, msk1); + z = vec_xor(z, y); + r->s = vec_xor(z, x); + lung->s = w; +} +#elif defined(HAVE_SSE2) +/** + * This function represents the recursion formula. + * @param r output 128-bit + * @param a a 128-bit part of the internal state array + * @param b a 128-bit part of the internal state array + * @param d a 128-bit part of the internal state array (I/O) + */ +inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *u) { + __m128i v, w, x, y, z; + + x = a->si; + z = _mm_slli_epi64(x, DSFMT_SL1); + y = _mm_shuffle_epi32(u->si, SSE2_SHUFF); + z = _mm_xor_si128(z, b->si); + y = _mm_xor_si128(y, z); + + v = _mm_srli_epi64(y, DSFMT_SR); + w = _mm_and_si128(y, sse2_param_mask.i128); + v = _mm_xor_si128(v, x); + v = _mm_xor_si128(v, w); + r->si = v; + u->si = y; +} +#else +/** + * This function represents the recursion formula. + * @param r output 128-bit + * @param a a 128-bit part of the internal state array + * @param b a 128-bit part of the internal state array + * @param lung a 128-bit part of the internal state array (I/O) + */ +inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b, + w128_t *lung) { + uint64_t t0, t1, L0, L1; + + t0 = a->u[0]; + t1 = a->u[1]; + L0 = lung->u[0]; + L1 = lung->u[1]; + lung->u[0] = (t0 << DSFMT_SL1) ^ (L1 >> 32) ^ (L1 << 32) ^ b->u[0]; + lung->u[1] = (t1 << DSFMT_SL1) ^ (L0 >> 32) ^ (L0 << 32) ^ b->u[1]; + r->u[0] = (lung->u[0] >> DSFMT_SR) ^ (lung->u[0] & DSFMT_MSK1) ^ t0; + r->u[1] = (lung->u[1] >> DSFMT_SR) ^ (lung->u[1] & DSFMT_MSK2) ^ t1; +} +#endif +#endif diff --git a/psychlops/core/math/dSFMT2.0/dSFMT-params.h b/psychlops/core/math/dSFMT2.0/dSFMT-params.h index a24e8ec..aa02478 100644 --- a/psychlops/core/math/dSFMT2.0/dSFMT-params.h +++ b/psychlops/core/math/dSFMT2.0/dSFMT-params.h @@ -39,7 +39,7 @@ #define SSE2_SHUFF 0x1b #elif defined(HAVE_ALTIVEC) #if defined(__APPLE__) /* For OSX */ - #define ALTI_SR (vector unsigned char)(4) + #define ALTI_SR (vector unsigned char)(4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4) #define ALTI_SR_PERM \ (vector unsigned char)(15,0,1,2,3,4,5,6,15,8,9,10,11,12,13,14) #define ALTI_SR_MSK \ @@ -47,7 +47,7 @@ #define ALTI_PERM \ (vector unsigned char)(12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3) #else - #define ALTI_SR {4} + #define ALTI_SR {4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4} #define ALTI_SR_PERM {15,0,1,2,3,4,5,6,15,8,9,10,11,12,13,14} #define ALTI_SR_MSK {0x000fffffU,0xffffffffU,0x000fffffU,0xffffffffU} #define ALTI_PERM {12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3} @@ -66,6 +66,14 @@ #include "dSFMT-params11213.h" #elif DSFMT_MEXP == 19937 #include "dSFMT-params19937.h" +#elif DSFMT_MEXP == 44497 + #include "dSFMT-params44497.h" +#elif DSFMT_MEXP == 86243 + #include "dSFMT-params86243.h" +#elif DSFMT_MEXP == 132049 + #include "dSFMT-params132049.h" +#elif DSFMT_MEXP == 216091 + #include "dSFMT-params216091.h" #else #ifdef __GNUC__ #error "DSFMT_MEXP is not valid." diff --git a/psychlops/core/math/dSFMT2.0/dSFMT-params19937.h b/psychlops/core/math/dSFMT2.0/dSFMT-params19937.h index 7f01846..a600b0d 100644 --- a/psychlops/core/math/dSFMT2.0/dSFMT-params19937.h +++ b/psychlops/core/math/dSFMT2.0/dSFMT-params19937.h @@ -20,7 +20,7 @@ /* PARAMETERS FOR ALTIVEC */ #if defined(__APPLE__) /* For OSX */ - #define ALTI_SL1 (vector unsigned int)(3, 3, 3, 3) + #define ALTI_SL1 (vector unsigned char)(3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3) #define ALTI_SL1_PERM \ (vector unsigned char)(2,3,4,5,6,7,30,30,10,11,12,13,14,15,0,1) #define ALTI_SL1_MSK \ @@ -28,7 +28,7 @@ #define ALTI_MSK (vector unsigned int)(DSFMT_MSK32_1, \ DSFMT_MSK32_2, DSFMT_MSK32_3, DSFMT_MSK32_4) #else /* For OTHER OSs(Linux?) */ - #define ALTI_SL1 {3, 3, 3, 3} + #define ALTI_SL1 {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3} #define ALTI_SL1_PERM \ {2,3,4,5,6,7,30,30,10,11,12,13,14,15,0,1} #define ALTI_SL1_MSK \ diff --git a/psychlops/core/math/dSFMT2.0/dSFMT.c b/psychlops/core/math/dSFMT2.0/dSFMT.c index bd9d157..e86449a 100644 --- a/psychlops/core/math/dSFMT2.0/dSFMT.c +++ b/psychlops/core/math/dSFMT2.0/dSFMT.c @@ -15,6 +15,11 @@ #include #include #include "dSFMT-params.h" +#include "dSFMT-common.h" + +#if defined(__cplusplus) +extern "C" { +#endif /** dsfmt internal state vector */ dsfmt_t dsfmt_global_data; @@ -26,30 +31,25 @@ static const int dsfmt_mexp = DSFMT_MEXP; ----------------*/ inline static uint32_t ini_func1(uint32_t x); inline static uint32_t ini_func2(uint32_t x); -inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t *array, int size); -inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t *array, int size); -inline static void gen_rand_array_o0c1(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_o0c1(dsfmt_t *dsfmt, w128_t *array, int size); -inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t *array, int size); inline static int idxof(int i); static void initial_mask(dsfmt_t *dsfmt); static void period_certification(dsfmt_t *dsfmt); #if defined(HAVE_SSE2) -# include -/** mask data for sse2 */ -static __m128i sse2_param_mask; /** 1 in 64bit for sse2 */ -static __m128i sse2_int_one; +static const union X128I_T sse2_int_one = {{1, 1}}; /** 2.0 double for sse2 */ -static __m128d sse2_double_two; +static const union X128D_T sse2_double_two = {{2.0, 2.0}}; /** -1.0 double for sse2 */ -static __m128d sse2_double_m_one; - -static void setup_const(void); +static const union X128D_T sse2_double_m_one = {{-1.0, -1.0}}; #endif /** @@ -66,105 +66,6 @@ inline static int idxof(int i) { } #endif -/** - * This function represents the recursion formula. - * @param r output - * @param a a 128-bit part of the internal state array - * @param b a 128-bit part of the internal state array - * @param lung a 128-bit part of the internal state array - */ -#if defined(HAVE_ALTIVEC) -inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b, - w128_t *lung) { - const vector unsigned char sl1 = ALTI_SL1; - const vector unsigned char sl1_perm = ALTI_SL1_PERM; - const vector unsigned int sl1_msk = ALTI_SL1_MSK; - const vector unsigned char sr1 = ALTI_SR; - const vector unsigned char sr1_perm = ALTI_SR_PERM; - const vector unsigned int sr1_msk = ALTI_SR_MSK; - const vector unsigned char perm = ALTI_PERM; - const vector unsigned int msk1 = ALTI_MSK; - vector unsigned int w, x, y, z; - - z = a->s; - w = lung->s; - x = vec_perm(w, (vector unsigned int)perm, perm); - y = vec_perm(z, sl1_perm, sl1_perm); - y = vec_sll(y, sl1); - y = vec_and(y, sl1_msk); - w = vec_xor(x, b->s); - w = vec_xor(w, y); - x = vec_perm(w, (vector unsigned int)sr1_perm, sr1_perm); - x = vec_srl(x, sr1); - x = vec_and(x, sr1_msk); - y = vec_and(w, msk1); - z = vec_xor(z, y); - r->s = vec_xor(z, x); - lung->s = w; -} -#elif defined(HAVE_SSE2) -/** - * This function setup some constant variables for SSE2. - */ -static void setup_const(void) { - static int first = 1; - if (!first) { - return; - } - sse2_param_mask = _mm_set_epi32(DSFMT_MSK32_3, DSFMT_MSK32_4, - DSFMT_MSK32_1, DSFMT_MSK32_2); - sse2_int_one = _mm_set_epi32(0, 1, 0, 1); - sse2_double_two = _mm_set_pd(2.0, 2.0); - sse2_double_m_one = _mm_set_pd(-1.0, -1.0); - first = 0; -} - -/** - * This function represents the recursion formula. - * @param r output 128-bit - * @param a a 128-bit part of the internal state array - * @param b a 128-bit part of the internal state array - * @param d a 128-bit part of the internal state array (I/O) - */ -inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *u) { - __m128i v, w, x, y, z; - - x = a->si; - z = _mm_slli_epi64(x, DSFMT_SL1); - y = _mm_shuffle_epi32(u->si, SSE2_SHUFF); - z = _mm_xor_si128(z, b->si); - y = _mm_xor_si128(y, z); - - v = _mm_srli_epi64(y, DSFMT_SR); - w = _mm_and_si128(y, sse2_param_mask); - v = _mm_xor_si128(v, x); - v = _mm_xor_si128(v, w); - r->si = v; - u->si = y; -} -#else /* standard C */ -/** - * This function represents the recursion formula. - * @param r output 128-bit - * @param a a 128-bit part of the internal state array - * @param b a 128-bit part of the internal state array - * @param lung a 128-bit part of the internal state array (I/O) - */ -inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b, - w128_t *lung) { - uint64_t t0, t1, L0, L1; - - t0 = a->u[0]; - t1 = a->u[1]; - L0 = lung->u[0]; - L1 = lung->u[1]; - lung->u[0] = (t0 << DSFMT_SL1) ^ (L1 >> 32) ^ (L1 << 32) ^ b->u[0]; - lung->u[1] = (t1 << DSFMT_SL1) ^ (L0 >> 32) ^ (L0 << 32) ^ b->u[1]; - r->u[0] = (lung->u[0] >> DSFMT_SR) ^ (lung->u[0] & DSFMT_MSK1) ^ t0; - r->u[1] = (lung->u[1] >> DSFMT_SR) ^ (lung->u[1] & DSFMT_MSK2) ^ t1; -} -#endif - #if defined(HAVE_SSE2) /** * This function converts the double precision floating point numbers which @@ -173,7 +74,7 @@ inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b, * @param w 128bit stracture of double precision floating point numbers (I/O) */ inline static void convert_c0o1(w128_t *w) { - w->sd = _mm_add_pd(w->sd, sse2_double_m_one); + w->sd = _mm_add_pd(w->sd, sse2_double_m_one.d128); } /** @@ -183,7 +84,7 @@ inline static void convert_c0o1(w128_t *w) { * @param w 128bit stracture of double precision floating point numbers (I/O) */ inline static void convert_o0c1(w128_t *w) { - w->sd = _mm_sub_pd(sse2_double_two, w->sd); + w->sd = _mm_sub_pd(sse2_double_two.d128, w->sd); } /** @@ -193,8 +94,8 @@ inline static void convert_o0c1(w128_t *w) { * @param w 128bit stracture of double precision floating point numbers (I/O) */ inline static void convert_o0o1(w128_t *w) { - w->si = _mm_or_si128(w->si, sse2_int_one); - w->sd = _mm_add_pd(w->sd, sse2_double_m_one); + w->si = _mm_or_si128(w->si, sse2_int_one.i128); + w->sd = _mm_add_pd(w->sd, sse2_double_m_one.d128); } #else /* standard C and altivec */ /** @@ -240,7 +141,7 @@ inline static void convert_o0o1(w128_t *w) { * @param array an 128-bit array to be filled by pseudorandom numbers. * @param size number of 128-bit pseudorandom numbers to be generated. */ -inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t *array, int size) { int i, j; w128_t lung; @@ -278,7 +179,7 @@ inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t array[], * @param array an 128-bit array to be filled by pseudorandom numbers. * @param size number of 128-bit pseudorandom numbers to be generated. */ -inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t *array, int size) { int i, j; w128_t lung; @@ -321,7 +222,7 @@ inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t array[], * @param array an 128-bit array to be filled by pseudorandom numbers. * @param size number of 128-bit pseudorandom numbers to be generated. */ -inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t *array, int size) { int i, j; w128_t lung; @@ -364,7 +265,7 @@ inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t array[], * @param array an 128-bit array to be filled by pseudorandom numbers. * @param size number of 128-bit pseudorandom numbers to be generated. */ -inline static void gen_rand_array_o0c1(dsfmt_t *dsfmt, w128_t array[], +inline static void gen_rand_array_o0c1(dsfmt_t *dsfmt, w128_t *array, int size) { int i, j; w128_t lung; @@ -440,10 +341,14 @@ static void initial_mask(dsfmt_t *dsfmt) { * @param dsfmt dsfmt state vector. */ static void period_certification(dsfmt_t *dsfmt) { - int i, j; uint64_t pcv[2] = {DSFMT_PCV1, DSFMT_PCV2}; uint64_t tmp[2]; uint64_t inner; + int i; +#if (DSFMT_PCV2 & 1) != 1 + int j; + uint64_t work; +#endif tmp[0] = (dsfmt->status[DSFMT_N].u[0] ^ DSFMT_FIX1); tmp[1] = (dsfmt->status[DSFMT_N].u[1] ^ DSFMT_FIX2); @@ -462,7 +367,6 @@ static void period_certification(dsfmt_t *dsfmt) { #if (DSFMT_PCV2 & 1) == 1 dsfmt->status[DSFMT_N].u[1] ^= 1; #else - uint64_t work; for (i = 1; i >= 0; i--) { work = 1; for (j = 0; j < 64; j++) { @@ -637,9 +541,6 @@ void dsfmt_chk_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed, int mexp) { initial_mask(dsfmt); period_certification(dsfmt); dsfmt->idx = DSFMT_N64; -#if defined(HAVE_SSE2) - setup_const(); -#endif } /** @@ -688,7 +589,6 @@ void dsfmt_chk_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[], r += key_length; psfmt32[idxof((mid + lag) % size)] += r; psfmt32[idxof(0)] = r; - i = 1; count--; for (i = 1, j = 0; (j < count) && (j < key_length); j++) { r = ini_func1(psfmt32[idxof(i)] @@ -723,10 +623,11 @@ void dsfmt_chk_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[], initial_mask(dsfmt); period_certification(dsfmt); dsfmt->idx = DSFMT_N64; -#if defined(HAVE_SSE2) - setup_const(); -#endif } #if defined(__INTEL_COMPILER) # pragma warning(default:981) #endif + +#if defined(__cplusplus) +} +#endif diff --git a/psychlops/core/math/dSFMT2.0/dSFMT.h b/psychlops/core/math/dSFMT2.0/dSFMT.h index c04828d..65f1662 100644 --- a/psychlops/core/math/dSFMT2.0/dSFMT.h +++ b/psychlops/core/math/dSFMT2.0/dSFMT.h @@ -1,5 +1,6 @@ +#pragma once /** - * @file dSFMT_bcc.h + * @file dSFMT.h * * @brief double precision SIMD oriented Fast Mersenne Twister(dSFMT) * pseudorandom number generator based on IEEE 754 format. @@ -9,6 +10,9 @@ * * Copyright (C) 2007, 2008 Mutsuo Saito, Makoto Matsumoto and * Hiroshima University. All rights reserved. + * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, + * Hiroshima University and The University of Tokyo. + * All rights reserved. * * The new BSD License is applied to this software. * see LICENSE.txt @@ -30,6 +34,9 @@ #ifndef DSFMT_H #define DSFMT_H +#if defined(__cplusplus) +extern "C" { +#endif #include #include @@ -43,7 +50,7 @@ /*----------------- BASIC DEFINITIONS -----------------*/ -/** Mersenne Exponent. The period of the sequence +/* Mersenne Exponent. The period of the sequence * is a multiple of 2^DSFMT_MEXP-1. * #define DSFMT_MEXP 19937 */ /** DSFMT generator has an internal state array of 128-bit integers, @@ -85,27 +92,21 @@ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # include -#elif defined(_MSC_VER) -# if !defined(DSFMT_UINT32_DEFINED) && !defined(SFMT_UINT32_DEFINED) -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -# define DSFMT_UINT32_DEFINED -# if !defined(inline) -# define inline __inline -# endif -# endif -#elif defined(__BORLANDC__) +#elif defined(_MSC_VER) || defined(__BORLANDC__) # if !defined(DSFMT_UINT32_DEFINED) && !defined(SFMT_UINT32_DEFINED) typedef unsigned int uint32_t; typedef unsigned __int64 uint64_t; +# ifndef UINT64_C +# define UINT64_C(v) (v ## ui64) +# endif # define DSFMT_UINT32_DEFINED -# if !defined(inline) +# if !defined(inline) && !defined(__cplusplus) # define inline __inline # endif # endif #else # include -# if !defined(inline) +# if !defined(inline) && !defined(__cplusplus) # if defined(__GNUC__) # define inline __inline__ # else @@ -125,14 +126,9 @@ typedef unsigned __int64 uint64_t; #endif #ifndef UINT64_C -# if defined(__BORLANDC__) -# define UINT64_C(v) (v ## UI64) -# else -# define UINT64_C(v) (v ## ULL) -# endif +# define UINT64_C(v) (v ## ULL) #endif - /*------------------------------------------ 128-bit SIMD like data type for standard C ------------------------------------------*/ @@ -183,10 +179,6 @@ extern dsfmt_t dsfmt_global_data; /** dsfmt mexp for check */ extern const int dsfmt_global_mexp; -#ifdef _cplusplus -extern "C" { -#endif - void dsfmt_gen_rand_all(dsfmt_t *dsfmt); void dsfmt_fill_array_open_close(dsfmt_t *dsfmt, double array[], int size); void dsfmt_fill_array_close_open(dsfmt_t *dsfmt, double array[], int size); @@ -194,7 +186,7 @@ void dsfmt_fill_array_open_open(dsfmt_t *dsfmt, double array[], int size); void dsfmt_fill_array_close1_open2(dsfmt_t *dsfmt, double array[], int size); void dsfmt_chk_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed, int mexp); void dsfmt_chk_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[], - int key_length, int mexp); + int key_length, int mexp); const char *dsfmt_get_idstring(void); int dsfmt_get_min_array_size(void); @@ -202,12 +194,13 @@ int dsfmt_get_min_array_size(void); # define DSFMT_PRE_INLINE inline static # define DSFMT_PST_INLINE __attribute__((always_inline)) #elif defined(_MSC_VER) && _MSC_VER >= 1200 -# define DSFMT_PRE_INLINE __forceinline +# define DSFMT_PRE_INLINE __forceinline static # define DSFMT_PST_INLINE #else # define DSFMT_PRE_INLINE inline static # define DSFMT_PST_INLINE #endif +DSFMT_PRE_INLINE uint32_t dsfmt_genrand_uint32(dsfmt_t *dsfmt) DSFMT_PST_INLINE; DSFMT_PRE_INLINE double dsfmt_genrand_close1_open2(dsfmt_t *dsfmt) DSFMT_PST_INLINE; DSFMT_PRE_INLINE double dsfmt_genrand_close_open(dsfmt_t *dsfmt) @@ -216,6 +209,7 @@ DSFMT_PRE_INLINE double dsfmt_genrand_open_close(dsfmt_t *dsfmt) DSFMT_PST_INLINE; DSFMT_PRE_INLINE double dsfmt_genrand_open_open(dsfmt_t *dsfmt) DSFMT_PST_INLINE; +DSFMT_PRE_INLINE uint32_t dsfmt_gv_genrand_uint32(void) DSFMT_PST_INLINE; DSFMT_PRE_INLINE double dsfmt_gv_genrand_close1_open2(void) DSFMT_PST_INLINE; DSFMT_PRE_INLINE double dsfmt_gv_genrand_close_open(void) DSFMT_PST_INLINE; DSFMT_PRE_INLINE double dsfmt_gv_genrand_open_close(void) DSFMT_PST_INLINE; @@ -230,11 +224,31 @@ DSFMT_PRE_INLINE void dsfmt_gv_fill_array_close1_open2(double array[], int size) DSFMT_PST_INLINE; DSFMT_PRE_INLINE void dsfmt_gv_init_gen_rand(uint32_t seed) DSFMT_PST_INLINE; DSFMT_PRE_INLINE void dsfmt_gv_init_by_array(uint32_t init_key[], - int key_length) DSFMT_PST_INLINE; + int key_length) DSFMT_PST_INLINE; DSFMT_PRE_INLINE void dsfmt_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed) DSFMT_PST_INLINE; DSFMT_PRE_INLINE void dsfmt_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[], - int key_length) DSFMT_PST_INLINE; + int key_length) DSFMT_PST_INLINE; + +/** + * This function generates and returns unsigned 32-bit integer. + * This is slower than SFMT, only for convenience usage. + * dsfmt_init_gen_rand() or dsfmt_init_by_array() must be called + * before this function. + * @param dsfmt dsfmt internal state date + * @return double precision floating point pseudorandom number + */ +inline static uint32_t dsfmt_genrand_uint32(dsfmt_t *dsfmt) { + uint32_t r; + uint64_t *psfmt64 = &dsfmt->status[0].u[0]; + + if (dsfmt->idx >= DSFMT_N64) { + dsfmt_gen_rand_all(dsfmt); + dsfmt->idx = 0; + } + r = psfmt64[dsfmt->idx++] & 0xffffffffU; + return r; +} /** * This function generates and returns double precision pseudorandom @@ -250,17 +264,27 @@ inline static double dsfmt_genrand_close1_open2(dsfmt_t *dsfmt) { double *psfmt64 = &dsfmt->status[0].d[0]; if (dsfmt->idx >= DSFMT_N64) { - dsfmt_gen_rand_all(dsfmt); - dsfmt->idx = 0; + dsfmt_gen_rand_all(dsfmt); + dsfmt->idx = 0; } r = psfmt64[dsfmt->idx++]; return r; } /** + * This function generates and returns unsigned 32-bit integer. + * This is slower than SFMT, only for convenience usage. + * dsfmt_gv_init_gen_rand() or dsfmt_gv_init_by_array() must be called + * before this function. This function uses \b global variables. + * @return double precision floating point pseudorandom number + */ +inline static uint32_t dsfmt_gv_genrand_uint32(void) { + return dsfmt_genrand_uint32(&dsfmt_global_data); +} + +/** * This function generates and returns double precision pseudorandom - * number which distributes uniformly in the range [1, 2). This is - * the primitive and faster than generating numbers in other ranges. + * number which distributes uniformly in the range [1, 2). * dsfmt_gv_init_gen_rand() or dsfmt_gv_init_by_array() must be called * before this function. This function uses \b global variables. * @return double precision floating point pseudorandom number @@ -326,13 +350,13 @@ inline static double dsfmt_gv_genrand_open_close(void) { inline static double dsfmt_genrand_open_open(dsfmt_t *dsfmt) { double *dsfmt64 = &dsfmt->status[0].d[0]; union { - double d; - uint64_t u; + double d; + uint64_t u; } r; if (dsfmt->idx >= DSFMT_N64) { - dsfmt_gen_rand_all(dsfmt); - dsfmt->idx = 0; + dsfmt_gen_rand_all(dsfmt); + dsfmt->idx = 0; } r.d = dsfmt64[dsfmt->idx++]; r.u |= 1; @@ -441,7 +465,7 @@ inline static void dsfmt_gv_init_gen_rand(uint32_t seed) { * @param key_length the length of init_key. */ inline static void dsfmt_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[], - int key_length) { + int key_length) { dsfmt_chk_init_by_array(dsfmt, init_key, key_length, DSFMT_MEXP); } @@ -605,7 +629,7 @@ inline static void fill_array_close1_open2(double array[], int size) { } #endif /* DSFMT_DO_NOT_USE_OLD_NAMES */ -#ifdef _cplusplus +#if defined(__cplusplus) } #endif diff --git a/win32gl/dev/psychlopswin32.cbp b/win32gl/dev/psychlopswin32.cbp index b690a3e..17308f4 100644 --- a/win32gl/dev/psychlopswin32.cbp +++ b/win32gl/dev/psychlopswin32.cbp @@ -149,10 +149,10 @@