# include <fmt/core.h>
# include <string>
# include <fuc2/testing.hpp>
# include "stats.hpp"
using namespace fuc2 ;
namespace perf_tests {
struct LargeSOA {
std : : vector < int > a01 ;
std : : vector < int > a02 ;
std : : vector < int > a03 ;
std : : vector < int > a04 ;
std : : vector < int > a05 ;
std : : vector < int > a06 ;
std : : vector < int > a07 ;
std : : vector < int > a08 ;
std : : vector < int > a09 ;
std : : vector < int > a10 ;
std : : vector < int > a11 ;
std : : vector < int > a12 ;
std : : vector < int > a13 ;
std : : vector < int > a14 ;
std : : vector < int > a15 ;
std : : vector < int > a16 ;
std : : vector < int > a17 ;
std : : vector < int > a18 ;
std : : vector < int > a19 ;
std : : vector < int > a20 ;
void push_back ( int x ) {
a01 . push_back ( x ) ;
a02 . push_back ( x ) ;
a03 . push_back ( x ) ;
a04 . push_back ( x ) ;
a05 . push_back ( x ) ;
a06 . push_back ( x ) ;
a07 . push_back ( x ) ;
a08 . push_back ( x ) ;
a09 . push_back ( x ) ;
a10 . push_back ( x ) ;
a11 . push_back ( x ) ;
a12 . push_back ( x ) ;
a13 . push_back ( x ) ;
a14 . push_back ( x ) ;
a15 . push_back ( x ) ;
a16 . push_back ( x ) ;
a17 . push_back ( x ) ;
a18 . push_back ( x ) ;
a19 . push_back ( x ) ;
a20 . push_back ( x ) ;
}
} ;
struct LargeStruct {
int a01 ;
int a02 ;
int a03 ;
int a04 ;
int a05 ;
int a06 ;
int a07 ;
int a08 ;
int a09 ;
int a10 ;
int a11 ;
int a12 ;
int a13 ;
int a14 ;
int a15 ;
int a16 ;
int a17 ;
int a18 ;
int a19 ;
int a20 ;
LargeStruct ( int x ) :
a01 ( x ) ,
a02 ( x ) ,
a03 ( x ) ,
a04 ( x ) ,
a05 ( x ) ,
a06 ( x ) ,
a07 ( x ) ,
a08 ( x ) ,
a09 ( x ) ,
a10 ( x ) ,
a11 ( x ) ,
a12 ( x ) ,
a13 ( x ) ,
a14 ( x ) ,
a15 ( x ) ,
a16 ( x ) ,
a17 ( x ) ,
a18 ( x ) ,
a19 ( x ) ,
a20 ( x ) { }
} ;
struct S1 {
int a01 ;
int a02 ;
int a03 ;
int a04 ;
S1 ( int x ) : a01 ( x ) , a02 ( x ) , a03 ( x ) , a04 ( x ) { }
} ;
struct S2 {
int a05 ;
int a06 ;
int a07 ;
int a08 ;
S2 ( int x ) : a05 ( x ) , a06 ( x ) , a07 ( x ) , a08 ( x ) { }
} ;
struct S3 {
int a09 ;
int a10 ;
int a11 ;
int a12 ;
S3 ( int x ) : a09 ( x ) , a10 ( x ) , a11 ( x ) , a12 ( x ) { }
} ;
struct S4 {
int a13 ;
int a14 ;
int a15 ;
int a16 ;
S4 ( int x ) : a13 ( x ) , a14 ( x ) , a15 ( x ) , a16 ( x ) { }
} ;
struct S5 {
int a17 ;
int a18 ;
int a19 ;
int a20 ;
S5 ( int x ) : a17 ( x ) , a18 ( x ) , a19 ( x ) , a20 ( x ) { }
} ;
struct MultipleSOA {
std : : vector < S1 > s1 ;
std : : vector < S2 > s2 ;
std : : vector < S3 > s3 ;
std : : vector < S4 > s4 ;
std : : vector < S5 > s5 ;
void push_back ( int x ) {
s1 . push_back ( { x } ) ;
s2 . push_back ( { x } ) ;
s3 . push_back ( { x } ) ;
s4 . push_back ( { x } ) ;
s5 . push_back ( { x } ) ;
}
} ;
struct Samples {
std : : vector < Stats > soa_big_for ;
std : : vector < Stats > soa_many_for ;
std : : vector < Stats > ls_big_for ;
std : : vector < Stats > ls_many_for ;
std : : vector < Stats > ls_many_for_fast ;
std : : vector < Stats > moa_big_for ;
std : : vector < Stats > moa_many_for ;
std : : vector < Stats > moa_many_for_fast ;
} ;
void run_test ( Samples & samples , int sample_size , int sample_number ) {
auto soa = new LargeSOA ( ) ;
auto ls = new std : : vector < LargeStruct > ;
auto moa = new MultipleSOA ( ) ;
for ( int i = 0 ; i < sample_size ; i + + ) {
soa - > push_back ( i ) ;
ls - > push_back ( { i } ) ;
moa - > push_back ( i ) ;
}
fmt : : println ( " Data Size: {} " , sizeof ( LargeStruct ) * sample_size ) ;
Stats big_for ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = big_for . time_start ( ) ;
for ( int i = 0 ; i < sample_size ; i + + ) {
soa - > a01 [ i ] + = soa - > a02 [ i ] + i ;
soa - > a02 [ i ] + = soa - > a03 [ i ] + i ;
soa - > a03 [ i ] + = soa - > a04 [ i ] + i ;
soa - > a04 [ i ] + = soa - > a05 [ i ] + i ;
soa - > a05 [ i ] + = soa - > a06 [ i ] + i ;
soa - > a06 [ i ] + = soa - > a07 [ i ] + i ;
soa - > a07 [ i ] + = soa - > a08 [ i ] + i ;
soa - > a08 [ i ] + = soa - > a09 [ i ] + i ;
soa - > a09 [ i ] + = soa - > a10 [ i ] + i ;
soa - > a10 [ i ] + = soa - > a11 [ i ] + i ;
soa - > a11 [ i ] + = soa - > a12 [ i ] + i ;
soa - > a12 [ i ] + = soa - > a13 [ i ] + i ;
soa - > a13 [ i ] + = soa - > a14 [ i ] + i ;
soa - > a14 [ i ] + = soa - > a15 [ i ] + i ;
soa - > a15 [ i ] + = soa - > a16 [ i ] + i ;
soa - > a16 [ i ] + = soa - > a17 [ i ] + i ;
soa - > a17 [ i ] + = soa - > a18 [ i ] + i ;
soa - > a18 [ i ] + = soa - > a19 [ i ] + i ;
soa - > a19 [ i ] + = soa - > a20 [ i ] + i ;
}
big_for . sample_time ( start ) ;
}
big_for . dump ( " soa big for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . soa_big_for . push_back ( big_for ) ;
Stats many_for ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = many_for . time_start ( ) ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a01 [ i ] + = soa - > a02 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a02 [ i ] + = soa - > a03 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a03 [ i ] + = soa - > a04 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a04 [ i ] + = soa - > a05 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a05 [ i ] + = soa - > a06 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a06 [ i ] + = soa - > a07 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a07 [ i ] + = soa - > a08 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a08 [ i ] + = soa - > a09 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a09 [ i ] + = soa - > a10 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a10 [ i ] + = soa - > a11 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a11 [ i ] + = soa - > a12 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a12 [ i ] + = soa - > a13 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a13 [ i ] + = soa - > a14 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a14 [ i ] + = soa - > a15 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a15 [ i ] + = soa - > a16 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a16 [ i ] + = soa - > a17 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a17 [ i ] + = soa - > a18 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a18 [ i ] + = soa - > a19 [ i ] + i ;
for ( int i = 0 ; i < sample_size ; i + + ) soa - > a19 [ i ] + = soa - > a20 [ i ] + i ;
many_for . sample_time ( start ) ;
}
many_for . dump ( " soa many for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . soa_many_for . push_back ( many_for ) ;
Stats ls_big_for ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = ls_big_for . time_start ( ) ;
for ( auto & el : * ls ) {
el . a01 + = el . a02 + i ;
el . a02 + = el . a03 + i ;
el . a03 + = el . a04 + i ;
el . a04 + = el . a05 + i ;
el . a05 + = el . a06 + i ;
el . a06 + = el . a07 + i ;
el . a07 + = el . a08 + i ;
el . a08 + = el . a09 + i ;
el . a09 + = el . a10 + i ;
el . a10 + = el . a11 + i ;
el . a11 + = el . a12 + i ;
el . a12 + = el . a13 + i ;
el . a13 + = el . a14 + i ;
el . a14 + = el . a15 + i ;
el . a15 + = el . a16 + i ;
el . a16 + = el . a17 + i ;
el . a17 + = el . a18 + i ;
el . a18 + = el . a19 + i ;
el . a19 + = el . a20 + i ;
}
ls_big_for . sample_time ( start ) ;
}
ls_big_for . dump ( " ls big for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . ls_big_for . push_back ( ls_big_for ) ;
Stats ls_many_for ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = ls_many_for . time_start ( ) ;
for ( auto & el : * ls ) el . a01 + = el . a02 + i ;
for ( auto & el : * ls ) el . a02 + = el . a03 + i ;
for ( auto & el : * ls ) el . a03 + = el . a04 + i ;
for ( auto & el : * ls ) el . a04 + = el . a05 + i ;
for ( auto & el : * ls ) el . a05 + = el . a06 + i ;
for ( auto & el : * ls ) el . a06 + = el . a07 + i ;
for ( auto & el : * ls ) el . a07 + = el . a08 + i ;
for ( auto & el : * ls ) el . a08 + = el . a09 + i ;
for ( auto & el : * ls ) el . a09 + = el . a10 + i ;
for ( auto & el : * ls ) el . a10 + = el . a11 + i ;
for ( auto & el : * ls ) el . a11 + = el . a12 + i ;
for ( auto & el : * ls ) el . a12 + = el . a13 + i ;
for ( auto & el : * ls ) el . a13 + = el . a14 + i ;
for ( auto & el : * ls ) el . a14 + = el . a15 + i ;
for ( auto & el : * ls ) el . a15 + = el . a16 + i ;
for ( auto & el : * ls ) el . a16 + = el . a17 + i ;
for ( auto & el : * ls ) el . a17 + = el . a18 + i ;
for ( auto & el : * ls ) el . a18 + = el . a19 + i ;
for ( auto & el : * ls ) el . a19 + = el . a20 + i ;
ls_many_for . sample_time ( start ) ;
}
ls_many_for . dump ( " ls many for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . ls_many_for . push_back ( ls_many_for ) ;
Stats ls_many_for_fast ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = ls_many_for_fast . time_start ( ) ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a01 + = ( * ls ) [ i ] . a02 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a02 + = ( * ls ) [ i ] . a03 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a03 + = ( * ls ) [ i ] . a04 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a04 + = ( * ls ) [ i ] . a05 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a05 + = ( * ls ) [ i ] . a06 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a06 + = ( * ls ) [ i ] . a07 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a07 + = ( * ls ) [ i ] . a08 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a08 + = ( * ls ) [ i ] . a09 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a09 + = ( * ls ) [ i ] . a10 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a10 + = ( * ls ) [ i ] . a11 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a11 + = ( * ls ) [ i ] . a12 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a12 + = ( * ls ) [ i ] . a13 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a13 + = ( * ls ) [ i ] . a14 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a14 + = ( * ls ) [ i ] . a15 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a15 + = ( * ls ) [ i ] . a16 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a16 + = ( * ls ) [ i ] . a17 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a17 + = ( * ls ) [ i ] . a18 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a18 + = ( * ls ) [ i ] . a19 + i ;
for ( int i = 0 ; i < sample_size ; i + + ) ( * ls ) [ i ] . a19 + = ( * ls ) [ i ] . a20 + i ;
ls_many_for_fast . sample_time ( start ) ;
}
ls_many_for_fast . dump ( " ls many for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . ls_many_for_fast . push_back ( ls_many_for_fast ) ;
Stats moa_big_for ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = moa_big_for . time_start ( ) ;
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s1 [ i ] . a01 + = moa - > s1 [ i ] . a02 + i ;
moa - > s1 [ i ] . a02 + = moa - > s1 [ i ] . a03 + i ;
moa - > s1 [ i ] . a03 + = moa - > s1 [ i ] . a04 + i ;
moa - > s1 [ i ] . a04 + = moa - > s2 [ i ] . a05 + i ;
moa - > s2 [ i ] . a05 + = moa - > s2 [ i ] . a06 + i ;
moa - > s2 [ i ] . a06 + = moa - > s2 [ i ] . a07 + i ;
moa - > s2 [ i ] . a07 + = moa - > s2 [ i ] . a08 + i ;
moa - > s2 [ i ] . a08 + = moa - > s3 [ i ] . a09 + i ;
moa - > s3 [ i ] . a09 + = moa - > s3 [ i ] . a10 + i ;
moa - > s3 [ i ] . a10 + = moa - > s3 [ i ] . a11 + i ;
moa - > s3 [ i ] . a11 + = moa - > s3 [ i ] . a12 + i ;
moa - > s3 [ i ] . a12 + = moa - > s4 [ i ] . a13 + i ;
moa - > s4 [ i ] . a13 + = moa - > s4 [ i ] . a14 + i ;
moa - > s4 [ i ] . a14 + = moa - > s4 [ i ] . a15 + i ;
moa - > s4 [ i ] . a15 + = moa - > s4 [ i ] . a16 + i ;
moa - > s4 [ i ] . a16 + = moa - > s5 [ i ] . a17 + i ;
moa - > s5 [ i ] . a17 + = moa - > s5 [ i ] . a18 + i ;
moa - > s5 [ i ] . a18 + = moa - > s5 [ i ] . a19 + i ;
moa - > s5 [ i ] . a19 + = moa - > s5 [ i ] . a20 + i ;
}
moa_big_for . sample_time ( start ) ;
}
moa_big_for . dump ( " moa big for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . moa_big_for . push_back ( moa_big_for ) ;
Stats moa_many_for ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = moa_many_for . time_start ( ) ;
for ( auto & el : moa - > s1 ) {
el . a01 + = el . a02 + i ;
el . a02 + = el . a03 + i ;
el . a03 + = el . a04 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s1 [ i ] . a04 + = moa - > s2 [ i ] . a05 + i ;
}
for ( auto & el : moa - > s2 ) {
el . a05 + = el . a06 + i ;
el . a06 + = el . a07 + i ;
el . a07 + = el . a08 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s2 [ i ] . a08 + = moa - > s3 [ i ] . a09 + i ;
}
for ( auto & el : moa - > s3 ) {
el . a09 + = el . a10 + i ;
el . a10 + = el . a11 + i ;
el . a11 + = el . a12 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s3 [ i ] . a12 + = moa - > s4 [ i ] . a13 + i ;
}
for ( auto & el : moa - > s4 ) {
el . a13 + = el . a14 + i ;
el . a14 + = el . a15 + i ;
el . a15 + = el . a16 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s4 [ i ] . a16 + = moa - > s5 [ i ] . a17 + i ;
}
for ( auto & el : moa - > s5 ) {
el . a17 + = el . a18 + i ;
el . a18 + = el . a19 + i ;
el . a19 + = el . a20 + i ;
}
moa_many_for . sample_time ( start ) ;
}
moa_many_for . dump ( " moa many for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . moa_many_for . push_back ( moa_many_for ) ;
Stats moa_many_for_fast ;
for ( int i = 0 ; i < sample_number ; i + + ) {
auto start = moa_many_for_fast . time_start ( ) ;
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s1 [ i ] . a01 + = moa - > s1 [ i ] . a02 + i ;
moa - > s1 [ i ] . a02 + = moa - > s1 [ i ] . a03 + i ;
moa - > s1 [ i ] . a03 + = moa - > s1 [ i ] . a04 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s1 [ i ] . a04 + = moa - > s2 [ i ] . a05 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s2 [ i ] . a05 + = moa - > s2 [ i ] . a06 + i ;
moa - > s2 [ i ] . a06 + = moa - > s2 [ i ] . a07 + i ;
moa - > s2 [ i ] . a07 + = moa - > s2 [ i ] . a08 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s2 [ i ] . a08 + = moa - > s3 [ i ] . a09 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s3 [ i ] . a09 + = moa - > s3 [ i ] . a10 + i ;
moa - > s3 [ i ] . a10 + = moa - > s3 [ i ] . a11 + i ;
moa - > s3 [ i ] . a11 + = moa - > s3 [ i ] . a12 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s3 [ i ] . a12 + = moa - > s4 [ i ] . a13 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s4 [ i ] . a13 + = moa - > s4 [ i ] . a14 + i ;
moa - > s4 [ i ] . a14 + = moa - > s4 [ i ] . a15 + i ;
moa - > s4 [ i ] . a15 + = moa - > s4 [ i ] . a16 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s4 [ i ] . a16 + = moa - > s5 [ i ] . a17 + i ;
}
for ( int i = 0 ; i < sample_size ; i + + ) {
moa - > s5 [ i ] . a17 + = moa - > s5 [ i ] . a18 + i ;
moa - > s5 [ i ] . a18 + = moa - > s5 [ i ] . a19 + i ;
moa - > s5 [ i ] . a19 + = moa - > s5 [ i ] . a20 + i ;
}
moa_many_for_fast . sample_time ( start ) ;
}
moa_many_for_fast . dump ( " moa many for " ) ;
fmt : : println ( " ------------- \n " ) ;
samples . moa_many_for_fast . push_back ( moa_many_for_fast ) ;
}
void test_soa_performance ( ) {
Samples samples ;
for ( int i = 0 ; i < 10 ; i + + ) {
run_test ( samples , 100 , 100 ) ;
}
for ( size_t i = 0 ; i < samples . soa_big_for . size ( ) ; i + + ) {
fmt : : println ( " {:.2f} {:.2f} {:.2f} {:.2f}!={:.2f} {:.2f} {:.2f}!={:.2f} " ,
samples . soa_big_for [ i ] . mean ( ) ,
samples . soa_many_for [ i ] . mean ( ) ,
samples . ls_big_for [ i ] . mean ( ) ,
samples . ls_many_for [ i ] . mean ( ) ,
samples . ls_many_for_fast [ i ] . mean ( ) ,
samples . moa_big_for [ i ] . mean ( ) ,
samples . moa_many_for [ i ] . mean ( ) ,
samples . moa_many_for_fast [ i ] . mean ( ) ) ;
}
}
fuc2 : : Set TESTS {
. name = " perf " ,
. tests = {
TEST ( test_soa_performance ) ,
}
} ;
}