diff --git a/test/GNUmakefile b/test/GNUmakefile index 109fd7c2e1..e6dfe435e1 100644 --- a/test/GNUmakefile +++ b/test/GNUmakefile @@ -184,16 +184,23 @@ endif # benchmark # bench: benchmark -benchmark: - @if [ -a _time.log ]; then rm _time.log; fi - num=1; while [[ $$num -le 10 ]]; do \ +benchmark: benchmark_basis_ benchmark_main_ + @awk 'BEGIN{ sum=0; max=0; min=-1; num=0; } \ + { if($$1=="user") { num+=1; if(min==-1){ min=$$2; } sum+=$$2; if($$2>max){max=$$2}; if(min>$$2){min=$$2}; } }\ + END{ num-=2; sum-=min; sum-=max; print("basis", sum/num); }' benchmark_basis_time.log >> benchmark_main_time.log + @awk 'BEGIN{ sum=0; max=0; min=-1; num=0; basis=0; } \ + { if($$1=="user") { num+=1; if(min==-1){ min=$$2; } sum+=$$2; if($$2>max){max=$$2}; if(min>$$2){min=$$2}; } }\ + { if($$1=="basis") { basis=$$2; } } \ + END{ print("Total:", sum, "(",num,")" ); num-=2; sum-=min; sum-=max; print("Min:", min); print("Max:", max); \ + print("Avg:", sum/num); print("per basis:", (sum/num)/basis); }' benchmark_main_time.log + +benchmark_main_ benchmark_basis_: + @if [ -a $@time.log ]; then rm $@time.log; fi + @num=1; while [[ $$num -le 10 ]]; do \ make -C benchmark clean; \ - { time -p make -C benchmark build 2>&1; } 2>> _time.log; \ + { time -p make -C benchmark $@ 2>&1; } 2>> $@time.log; \ ((num = num + 1)); \ done - @awk 'BEGIN{ sum=0; max=0; min=-1; num=0; } \ - { if($$1=="user") { num+=1; if(min==-1){ min=$$2; } sum+=$$2; if($$2>max){max=$$2}; if(min>$$2){min=$$2}; } }\ - END{ print("Total:", sum, "(",num,")" ); print("Min:", min); print("Max:", max); print("Avg:", sum/num); }' _time.log # # diff --git a/test/benchmark/GNUmakefile b/test/benchmark/GNUmakefile index cc71a35003..f6a731ac93 100644 --- a/test/benchmark/GNUmakefile +++ b/test/benchmark/GNUmakefile @@ -101,6 +101,7 @@ BENCH_SRCS = benchmark_n0.cpp \ OBJS = $(SRCS:%.cpp=%.o) $(BENCH_SRCS:%.cpp=%.o) TARGET = benchmark +BASIS = basis # # build targets. @@ -109,19 +110,24 @@ TARGET = benchmark .PHONY: clean default all run test build default : build +benchmark_main_: build +benchmark_basis_: $(BASIS) build: $(TARGET) all : clean build test clean : - $(RM) $(TARGET) benchmark_n*.cpp *.o *.stackdump + $(RM) $(TARGET) $(BASIS) benchmark_n*.cpp *.o *.stackdump check : test run : test test : $(TARGET) ./$< +$(BASIS): test.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) + benchmark_n%.cpp: benchmark_base.cpp @echo '#define PACKAGENAME benchmark_n$*' | cat - benchmark_base.cpp > $@ diff --git a/test/benchmark/test.cpp b/test/benchmark/test.cpp new file mode 100644 index 0000000000..293fc0b3a1 --- /dev/null +++ b/test/benchmark/test.cpp @@ -0,0 +1,225 @@ +//====================================================================== +//----------------------------------------------------------------------- +/** + * @file test.cpp + * @brief test + * + * @author t.shirayanagi + * @par copyright + * Copyright (C) 2014, Takazumi Shirayanagi\n + * This software is released under the new BSD License, + * see LICENSE +*/ +//----------------------------------------------------------------------- +//====================================================================== +#include + +#include "../../include/internal/iutest_pp.hpp" + +#define PP_CAT IUTEST_PP_CAT +#define PP_DEC IUTEST_PP_DEC + +namespace detail +{ + +typedef struct true_type +{ + static const bool value = true; +} true_type; + +// false +typedef struct false_type +{ + static const bool value = false; +} false_type; + +} + +template +struct type_select +{ + typedef YES_T type; +}; +template +struct type_select +{ + typedef NO_T type; +}; + +template +class is_prime_number +{ + static const intmax_t RECURSIVE_MAX=200; //!< template の再帰上限値 + + template + struct is_prime_calc_recursive0 + { + typedef typename type_select<(N%D1==0) || (N%D2==0), detail::false_type + , typename is_prime_calc_recursive0::type>::type type; + static const intmax_t TMP1 = ((D1)*(D1) > N) ? N : is_prime_calc_recursive0::TMP1; + static const intmax_t TMP2 = ((D2)*(D2) > N) ? N : is_prime_calc_recursive0::TMP2; + typedef char e[ Max ? 1 : -1]; + }; + template + struct is_prime_calc_recursive0 + { + static const intmax_t TMP1=D1; + static const intmax_t TMP2=N; + typedef detail::true_type type; + typedef char e[ Max ? 1 : -1]; + }; + template + struct is_prime_calc_recursive0 + { + static const intmax_t TMP1=N; + static const intmax_t TMP2=D2; + typedef detail::true_type type; + typedef char e[ Max ? 1 : -1]; + }; + template + struct is_prime_calc_recursive0 + { + static const intmax_t TMP1= D1; + static const intmax_t TMP2= D2; + typedef detail::true_type type; + typedef char e[ Max ? 1 : -1]; + }; + template + struct is_prime_calc_recursive0 + { + static const intmax_t TMP1=D1; + static const intmax_t TMP2=N; + typedef detail::true_type type; + typedef char e[ Max ? 1 : -1]; + }; + template + struct is_prime_calc_recursive0 + { + static const intmax_t TMP1=N; + static const intmax_t TMP2=D2; + typedef detail::true_type type; + typedef char e[ Max ? 1 : -1]; + }; + +#define PRIME_NUMBER_RECURSIVE_IMPL(index) \ + template \ + struct is_prime_calc_recursive##index \ + { \ + static const bool value = PP_CAT(is_prime_calc_recursive, PP_DEC(index))::type::value; \ + static const intmax_t TMP1 = PP_CAT(is_prime_calc_recursive, PP_DEC(index))::TMP1; \ + static const intmax_t TMP2 = PP_CAT(is_prime_calc_recursive, PP_DEC(index))::TMP2; \ + typedef typename type_select::type \ + , detail::false_type >::type type; \ + }; \ + template \ + struct is_prime_calc_recursive##index \ + { \ + static const intmax_t TMP1=D1; \ + static const intmax_t TMP2=D2; \ + typedef detail::true_type type; \ + }; \ + template \ + struct is_prime_calc_recursive##index \ + { \ + static const intmax_t TMP1=N; \ + static const intmax_t TMP2=D2; \ + typedef detail::true_type type; \ + }; \ + template \ + struct is_prime_calc_recursive##index \ + { \ + static const intmax_t TMP1=D1; \ + static const intmax_t TMP2=N; \ + typedef detail::true_type type; \ + }; \ + template \ + struct is_prime_calc_recursive##index \ + { \ + static const intmax_t TMP1=N; \ + static const intmax_t TMP2=N; \ + typedef detail::true_type type; \ + } + + PRIME_NUMBER_RECURSIVE_IMPL(1); + PRIME_NUMBER_RECURSIVE_IMPL(2); + PRIME_NUMBER_RECURSIVE_IMPL(3); + PRIME_NUMBER_RECURSIVE_IMPL(4); + PRIME_NUMBER_RECURSIVE_IMPL(5); + + +#undef PRIME_NUMBER_RECURSIVE_IMPL + +#define PRIME_NUMBER_RECURSIVE_LEVEL 5 + template + struct is_prime_calc_impl + { + static const bool value = PP_CAT(is_prime_calc_recursive, PRIME_NUMBER_RECURSIVE_LEVEL)::type::value; + static const intmax_t TMP1 = PP_CAT(is_prime_calc_recursive, PRIME_NUMBER_RECURSIVE_LEVEL)::TMP1; + static const intmax_t TMP2 = PP_CAT(is_prime_calc_recursive, PRIME_NUMBER_RECURSIVE_LEVEL)::TMP2; + typedef typename type_select::type + , detail::false_type >::type type; + }; +#undef PRIME_NUMBER_RECURSIVE_LEVEL + + template + struct is_prime_calc_impl { typedef detail::true_type type; }; + template + struct is_prime_calc_impl { typedef detail::true_type type; }; + template + struct is_prime_calc_impl { typedef detail::true_type type; }; + + template + struct is_prime_impl + { + typedef typename type_select<(N%3 == 0), detail::false_type + , typename type_select<(N%5 == 0), detail::false_type + , typename is_prime_calc_impl::type >::type >::type type; + }; + + template + struct is_prime_impl< 5, isSimpleFilter> { typedef detail::true_type type; }; // 5 は素数 + template + struct is_prime_impl< 3, isSimpleFilter> { typedef detail::true_type type; }; // 3 は素数 + template + struct is_prime_impl< 2, isSimpleFilter> { typedef detail::true_type type; }; // 2 は素数 + + template + struct is_prime_impl + { + typedef detail::false_type type; + }; + + typedef typename is_prime_impl 1) && (((V&1) == 1) || V == 2) >::type type; +public: + static const bool value = type::value; +}; + + +#define STATIC_ASSERT( B ) static_assert( B, #B ) + +#ifdef UNICODE +int wmain(int , wchar_t* []) +#else +int main(int , char* []) +#endif +{ + STATIC_ASSERT( is_prime_number<2>::value ); + STATIC_ASSERT( is_prime_number<3>::value ); + STATIC_ASSERT( is_prime_number<5>::value ); + STATIC_ASSERT( is_prime_number<7>::value ); + STATIC_ASSERT( is_prime_number<13>::value ); + STATIC_ASSERT( is_prime_number<17>::value ); + STATIC_ASSERT( is_prime_number<65497>::value ); + STATIC_ASSERT( is_prime_number<65491>::value == false ); +// STATIC_ASSERT( is_prime_number<16776989>::value ); +// STATIC_ASSERT( is_prime_number<37329287>::value ); + STATIC_ASSERT( is_prime_number<74746003>::value ); +// STATIC_ASSERT( is_prime_number<106591073>::value ); +// STATIC_ASSERT( is_prime_number<268435399>::value ); +// STATIC_ASSERT( is_prime_number<1073741789>::value ); + + return 0; +} +