Bonjour,

j'utilise Java Native Interface pour appeler ce code C++:
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
template<class T> inline void Maximum(const T *array1, const T *array2, const size_t size, T *result)
	{
	for (size_t i=0 ; i < size ; i++)
		result[i] = array1[i] > array2[i] ? array1[i] : array2[i] ;
	}
 
#ifdef __SSE2__
template<> inline void Maximum<UINT8>(const UINT8 *array1, const UINT8 *array2, const size_t size, UINT8 *result)
	{
	__m128i r0, r1 ;
 
	for (size_t i=0 ; i < size ; i+=16)
		{
		r0 = _mm_load_si128((__m128i *) array1) ;
		r1 = _mm_load_si128((__m128i *) array2) ;
		r1 = _mm_max_epu8(r0, r1) ;
		_mm_store_si128((__m128i *) result, r1) ; // Souci intermittent ici !!!
 
		array1 += 16 ;
		array2 += 16 ;
		result += 16 ;
		}
	}
#endif

et voici les appels depuis la classe cpp, en fonction que je traite un tableau de int ou de byte :
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
JNIEXPORT void JNICALL Java_arrayTiTi_ArrayMM_MaximumUnsigned___3B_3B_3B(JNIEnv *env, jclass obj, jbyteArray Array1, jbyteArray Array2, jbyteArray Result)
	{
	jsize length = env->GetArrayLength(Array1) ;
	UINT8 *array1 = (UINT8 *)env->GetPrimitiveArrayCritical(Array1, 0) ;
	UINT8 *array2 = (UINT8 *)env->GetPrimitiveArrayCritical(Array2, 0) ;
	jboolean copyres = JNI_FALSE ;
	UINT8 *result = (UINT8 *)env->GetPrimitiveArrayCritical(Result, &copyres) ;
	Maximum(array1, array2, length, result) ;
	env->ReleasePrimitiveArrayCritical(Array1, array1, JNI_ABORT) ;
	env->ReleasePrimitiveArrayCritical(Array2, array2, JNI_ABORT) ;
	env->ReleasePrimitiveArrayCritical(Result, result, copyres == JNI_TRUE ? 0 : JNI_ABORT) ;
	}
 
JNIEXPORT void JNICALL Java_arrayTiTi_ArrayMM_Maximum___3I_3I_3I(JNIEnv *env, jclass obj,
																jintArray Array1, jintArray Array2, jintArray Result)
	{
	jsize length = env->GetArrayLength(Array1) ;
	int *array1 = (int*)env->GetPrimitiveArrayCritical(Array1, 0) ;
	int *array2 = (int*)env->GetPrimitiveArrayCritical(Array2, 0) ;
	jboolean copyres = JNI_FALSE ;
	int *result = (int*)env->GetPrimitiveArrayCritical(Result, &copyres) ;
	Maximum(array1, array2, length, result) ;
	env->ReleasePrimitiveArrayCritical(Array1, array1, JNI_ABORT) ;
	env->ReleasePrimitiveArrayCritical(Array2, array2, JNI_ABORT) ;
	env->ReleasePrimitiveArrayCritical(Result, result, copyres == JNI_TRUE ? 0 : JNI_ABORT) ;
	}

Lorsque je fais passe des tableaux d'int, la simple boucle est appelée et tout se passe sans souci.
En revanche, lorsque je passe des tableaux de byte, la boucle avec les appels SSE2 est utilisé, mais parfois (environ une fois sur six), l'appel _mm_store_si128 génère une erreur.

Est ce que quelqu'un aurait une idée pourquoi ?