Am 26.03.2023 um 03:30 schrieb James Taylor:
> Sure if you can post a program that compiles in VS 2022 - 17.5.3
It's C++20. Maybe this works :
#include <iostream>
#include <random>
#include <chrono>
#include <vector>
#include <utility>
#include <atomic>
using namespace std;
using namespace chrono;
atomic_uint64_t aSum, aDenom = 3;
int main()
{
constexpr size_t
N = 0x400 / sizeof(uint64_t),
ROUNDS = 1'000'000;
mt19937_64 mt;
uniform_int_distribution<uint64_t> uid( (uint64_t)1 << 63, -1 );
vector<uint64_t> counters( N );
for( uint64_t &c : counters )
c = uid( mt );
auto unroll = []<size_t ... Indices, typename Fn>(
index_sequence<Indices ...>, Fn fn )
{
(fn.template operator ()<Indices>(), ...);
};
auto testPar = [&]<size_t Par>( integral_constant<size_t, Par> ) -> double
{
uint64_t prevs[Par] = { 0 };
auto seq = make_index_sequence<Par>();
auto start = high_resolution_clock::now();
uint64_t denom = ::aDenom.load( memory_order::relaxed );
for( size_t r = ROUNDS; r--; )
for( size_t i = 0; i + Par < N; i += Par )
unroll( seq, [&]<size_t I>() { prevs[I] = (counters[i + I] ^
prevs[I]) % denom; } );
double ns = duration_cast<nanoseconds>( high_resolution_clock::now() -
start ).count() / ((double)ROUNDS * N);
uint64_t sum = 0;
unroll( seq, [&]<size_t I>() { sum += prevs[I]; } );
::aSum.store( sum, memory_order::relaxed );
return ns;
};
unroll( make_index_sequence<4>(),
[&]<size_t I>()
{
cout << I << ": " << testPar( integral_constant<size_t, I + 1>() ) <<
endl;
} );
}