Mam taki kod:
#include <cstdint>
#include <cstdio>
#include <bitset>
#include <immintrin.h>
#include<iostream>
uint32_t multiply(uint32_t a, uint32_t b)
{
uint32_t p = 4194311;
uint64_t L = 1;
uint64_t c;
//__m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0, a), _mm_set_epi64x(0, b), 0);
//uint64_t c = _mm_cvtsi128_si64(result); // Extract low 64-bits of result
for (unsigned int i = 0; i < 32; ++i)
{
c ^= a & (L << i) ? (uint64_t)b << i : 0;
}
for (unsigned int i = 32; i --> 0; )
{
if (c & (L << (i + 32)))
{
c ^= L << (i + 32);
c ^= (uint64_t)p << i;
}
}
return (uint32_t)c;
}
I zwraca mi on za każdym razem inne wyniki dla ciągu pewnych iteracji. Problem jest w:
for (unsigned int i = 0; i < 32; ++i)
{
c ^= a & (L << i) ? (uint64_t)b << i : 0;
}
Bo gdy użyję zamiennie:
__m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0, a), _mm_set_epi64x(0, b), 0);
uint64_t c = _mm_cvtsi128_si64(result); // Extract low 64-bits of result
To wynik za każdym razem jest taki sam. Z tą zagadkową pętlą wyniki są różne, nawet, gdy uruchamiam w konsoli ten sam skompilowany już program.
Moja hipoteza jest taka, że gdzieś następuje jakieś przepełnienie i bity są ucinane w losowych miejscach lub jakoś podmieniane. Może w (uint64_t)b jest problem? c++ nie przestaje mnie zadziwiać, choć pewnie zaraz okaże się, że znów popełniam jakiś trywialny błąd.