00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <stdlib.h>
00032 #include <stdio.h>
00033
00034
00035 #define BIT_SCAN_DEBRUIJN
00036 #define BIT_SCAN_BRANCH
00037 #define BIT_SCAN_SLOW
00038
00039 #include "../bit_scan.h"
00040 #ifdef NO_PROFILE
00041 #define profile_init(x,y) do{}while(0)
00042 #define profile_start(x) do{}while(0)
00043 #define profile_end(x) do{}while(0)
00044 #define PROFILE_PRINT(x) do{}while(0)
00045 #else
00046 #include "profile.h"
00047 #endif
00048
00049 #define CHECK(txt, v1, val, f, pd) \
00050 do{ \
00051 unsigned long long ret; \
00052 profile_start(pd); \
00053 ret=(unsigned long long)f(val); \
00054 profile_end(pd); \
00055 if ((unsigned long long)v1!=ret){ \
00056 fprintf(stderr, "ERROR:" #f ": %s, expected %llx (%llx), got"\
00057 " %llx\n", \
00058 (txt), (unsigned long long)v1, \
00059 (unsigned long long)val, ret); \
00060 exit(-1); \
00061 } \
00062 }while(0)
00063
00064 #ifndef PROFILE_PRINT
00065 #define PROFILE_PRINT(pd) \
00066 do{ \
00067 printf("profile: %s (%ld/%ld) total %llu max %llu average %llu\n", \
00068 (pd)->name, (pd)->entries, (pd)->exits, \
00069 (pd)->total_cycles, (pd)->max_cycles, \
00070 (pd)->entries? \
00071 (pd)->total_cycles/(unsigned long long)(pd)->entries:0ULL ); \
00072 }while(0)
00073 #endif
00074
00075 int main(int argc, char** argv)
00076 {
00077 int r;
00078 unsigned int v;
00079 unsigned long long ll;
00080 int i;
00081 #ifndef NO_PROFILE
00082 struct profile_data pdf1, pdf2, pdf4, pdf5, pdf6, pdf8;
00083 struct profile_data pdl1, pdl2, pdl4, pdl5, pdl6, pdl8;
00084 #ifdef HAS_BIT_SCAN_ASM
00085 struct profile_data pdf3, pdf7, pdl3, pdl7;
00086 #endif
00087 struct profile_data pdf_32, pdf_64, pdl_32, pdl_64;
00088 struct profile_data pdf_long, pdl_long;
00089 #endif
00090
00091 profile_init(&pdf1, "first_debruijn32");
00092 profile_init(&pdf2, "first_slow32");
00093 #ifdef HAS_BIT_SCAN_ASM
00094 profile_init(&pdf3, "first_asm32");
00095 #endif
00096 profile_init(&pdf4, "first_br32");
00097 profile_init(&pdf5, "first_debruijn64");
00098 profile_init(&pdf6, "first_slow64");
00099 #ifdef HAS_BIT_SCAN_ASM
00100 profile_init(&pdf7, "first_asm64");
00101 #endif
00102 profile_init(&pdf8, "first_br64");
00103 profile_init(&pdl1, "last_debruijn32");
00104 profile_init(&pdl2, "last_slow32");
00105 #ifdef HAS_BIT_SCAN_ASM
00106 profile_init(&pdl3, "last_asm32");
00107 #endif
00108 profile_init(&pdl4, "last_br32");
00109 profile_init(&pdl5, "last_debruijn64");
00110 profile_init(&pdl6, "last_slow64");
00111 #ifdef HAS_BIT_SCAN_ASM
00112 profile_init(&pdl7, "last_asm64");
00113 #endif
00114 profile_init(&pdl8, "last_br64");
00115
00116 profile_init(&pdf_32, "scan_forward32");
00117 profile_init(&pdf_64, "scan_forward64");
00118 profile_init(&pdl_32, "scan_reverse32");
00119 profile_init(&pdl_64, "scan_reverse64");
00120 profile_init(&pdf_long, "scan_forward_l");
00121 profile_init(&pdl_long, "scan_reverse_l");
00122
00123
00124 for (i=0; i<100; i++){
00125 for (r=0; r<32; r++){
00126 v=(1U<<r);
00127 CHECK("first debruijn 32bit", r, v, bit_scan_forward_debruijn32, &pdf1);
00128 CHECK("first slow 32bit", r, v, bit_scan_forward_slow32, &pdf2);
00129 #ifdef HAS_BIT_SCAN_ASM
00130 CHECK("first asm 32bit", r, v, bit_scan_forward_asm32, &pdf3);
00131 #endif
00132 CHECK("first br 32bit", r, v, bit_scan_forward_br32, &pdf4);
00133 CHECK("scan_forward32", r, v, bit_scan_forward32, &pdf_32);
00134 if (sizeof(long)<=4){
00135 CHECK("scan_forward_l", r, v, bit_scan_forward, &pdf_long);
00136 }
00137 v+=(v-1);
00138 CHECK("last debruijn 32bit", r, v, bit_scan_reverse_debruijn32, &pdl1);
00139 CHECK("last slow 32bit", r, v, bit_scan_reverse_slow32, &pdl2);
00140 #ifdef HAS_BIT_SCAN_ASM
00141 CHECK("last asm 32bit", r, v, bit_scan_reverse_asm32, &pdl3);
00142 #endif
00143 CHECK("last br 32bit", r, v, bit_scan_reverse_br32, &pdl4);
00144 CHECK("scan_reverse32", r, v, bit_scan_reverse32, &pdl_32);
00145 if (sizeof(long)<=4){
00146 CHECK("scan_reverse_l", r, v, bit_scan_reverse, &pdl_long);
00147 }
00148 }
00149 for (r=0; r<64; r++){
00150 ll=(1ULL<<r);
00151 CHECK("first debruijn 64bit", r, ll, bit_scan_forward_debruijn64, &pdf5);
00152 CHECK("first slow 64bit", r, ll, bit_scan_forward_slow64, &pdf6);
00153 #ifdef HAS_BIT_SCAN_ASM
00154 CHECK("first asm 64bit", r, ll, bit_scan_forward_asm64, &pdf7);
00155 #endif
00156 CHECK("first br 64bit", r, ll, bit_scan_forward_br64, &pdf8);
00157 CHECK("scan_forward64", r, ll, bit_scan_forward64, &pdf_64);
00158 if (sizeof(long)>4){
00159 CHECK("scan_forward_l", r, ll, bit_scan_forward, &pdf_long);
00160 }
00161 ll+=ll-1;
00162 CHECK("last debruijn 64bit", r, ll, bit_scan_reverse_debruijn64, &pdl5);
00163 CHECK("last slow 64bit", r, ll, bit_scan_reverse_slow64, &pdl6);
00164 #ifdef HAS_BIT_SCAN_ASM
00165 CHECK("last asm 64bit", r, ll, bit_scan_reverse_asm64, &pdl7);
00166 #endif
00167 CHECK("last br 64bit", r, ll, bit_scan_reverse_br64, &pdl8);
00168 CHECK("scan_reverse64", r, ll, bit_scan_reverse64, &pdl_64);
00169 if (sizeof(long)>4){
00170 CHECK("scan_reverse_l", r, ll, bit_scan_reverse, &pdl_long);
00171 }
00172 }
00173 }
00174
00175 PROFILE_PRINT(&pdf1);
00176 PROFILE_PRINT(&pdf2);
00177 #ifdef HAS_BIT_SCAN_ASM
00178 PROFILE_PRINT(&pdf3);
00179 #endif
00180 PROFILE_PRINT(&pdf4);
00181 PROFILE_PRINT(&pdl1);
00182 PROFILE_PRINT(&pdl2);
00183 #ifdef HAS_BIT_SCAN_ASM
00184 PROFILE_PRINT(&pdl3);
00185 #endif
00186 PROFILE_PRINT(&pdl4);
00187 PROFILE_PRINT(&pdf5);
00188 PROFILE_PRINT(&pdf6);
00189 #ifdef HAS_BIT_SCAN_ASM
00190 PROFILE_PRINT(&pdf7);
00191 #endif
00192 PROFILE_PRINT(&pdf8);
00193 PROFILE_PRINT(&pdl5);
00194 PROFILE_PRINT(&pdl6);
00195 #ifdef HAS_BIT_SCAN_ASM
00196 PROFILE_PRINT(&pdl7);
00197 #endif
00198 PROFILE_PRINT(&pdl8);
00199
00200 PROFILE_PRINT(&pdf_32);
00201 PROFILE_PRINT(&pdf_64);
00202 PROFILE_PRINT(&pdf_long);
00203 PROFILE_PRINT(&pdl_32);
00204 PROFILE_PRINT(&pdl_64);
00205 PROFILE_PRINT(&pdl_long);
00206 return 0;
00207 }