diff options
author | Mattias Andrée <maandree@operamail.com> | 2015-10-16 20:43:50 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2015-10-16 20:43:50 +0200 |
commit | ad143de39cb8b76404ddd307b5d93328dbb06c5e (patch) | |
tree | 57ca6f6f2a3941493b4338aad50f69a748a79f36 | |
parent | info: fnindex (diff) | |
download | slibc-ad143de39cb8b76404ddd307b5d93328dbb06c5e.tar.gz slibc-ad143de39cb8b76404ddd307b5d93328dbb06c5e.tar.bz2 slibc-ad143de39cb8b76404ddd307b5d93328dbb06c5e.tar.xz |
heuristically determine int_fastN_t
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
-rw-r--r-- | gen/bits/intconf.c | 120 | ||||
-rw-r--r-- | gen/bits/intconf.h | 7 |
2 files changed, 112 insertions, 15 deletions
diff --git a/gen/bits/intconf.c b/gen/bits/intconf.c index 5955d38..2ba2754 100644 --- a/gen/bits/intconf.c +++ b/gen/bits/intconf.c @@ -16,24 +16,118 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> +#include <string.h> +#include <time.h> -int main(void) +/** + * On my amd64 machine, the usual result is: + * int_fast8_t = int32_t + * int_fast16_t = int32_t + * int_fast32_t = int32_t + * int_fast64_t = int64_t + */ + + +#define FAST_TEST(VAR) \ + n = 0, *VAR##p = 0; \ + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start)) \ + return perror(NULL), -1; \ + for (;;) \ + { \ + for (m = 1000; m--;) \ + VAR = 50, VAR += 50, VAR -= 50, VAR *= 50, VAR /= 50, VAR <<= 1, VAR >>= 1, *VAR##p |= 1; \ + n++; \ + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end)) \ + return perror(NULL), -1; \ + if (end.tv_sec > start.tv_sec + 2) \ + break; \ + if (end.tv_sec > start.tv_sec + 1) \ + if (end.tv_nsec >= start.tv_nsec) \ + break; \ + } \ + time_elapsed = (long long int)(end.tv_sec) * 1000000000LL; \ + time_elapsed += (long long int)(end.tv_nsec); \ + time_elapsed -= (long long int)(start.tv_sec) * 1000000000LL; \ + time_elapsed -= (long long int)(start.tv_nsec); \ + adjn = (double)n, adjn /= (double)time_elapsed / 1000000000.; \ + fprintf(stderr, "int%zu_t:%s %i000 op:s in %lli.%09lli s = %lf op:s/s\n", \ + 8 * sizeof(VAR), 8 * sizeof(VAR) < 10 ? " " : "", 8 * n, \ + time_elapsed / 1000000000LL, time_elapsed % 1000000000LL, adjn * 8000.); \ + if (adjn > bestn) \ + bestn = adjn, best = 8 * sizeof(VAR); \ + last = this + + +#define TEST(VAR) (this = 8 * (int)sizeof(VAR), ((this >= bits) && (this > last))) +#ifdef __GNUC__ +__attribute__((optimize("-O0"))) +#endif +static int fast(int bits) { - printf("CHAR_BIT %zu\n", 8 * sizeof(char)); - printf("SHORT_BIT %zu\n", 8 * sizeof(short int)); - printf("INT_BIT %zu\n", 8 * sizeof(int)); - printf("LONG_BIT %zu\n", 8 * sizeof(long int)); - printf("LONG_LONG_BIT %zu\n", 8 * sizeof(long long int)); - printf("PTR_BIT %zu\n", 8 * sizeof(void*)); + int last = 0, this = 0, best = 0, n, m; + float bestn; + float adjn; + struct timespec start, end; + long long int time_elapsed; - printf("INT%zu %s\n", 8 * sizeof(char), "char"); - printf("INT%zu %s\n", 8 * sizeof(short int), "short int"); - printf("INT%zu %s\n", 8 * sizeof(int), "int"); - printf("INT%zu %s\n", 8 * sizeof(long int), "long int"); - printf("INT%zu %s\n", 8 * sizeof(long long int), "long long int"); + register volatile char hhi; + register volatile short int hi; + register volatile int i; + register volatile long int li; + register volatile long long int lli; + volatile char hhip[1]; + volatile short int hip[1]; + volatile int ip[1]; + volatile long int lip[1]; + volatile long long int llip[1]; + + if (TEST(hhi)) { FAST_TEST(hhi); } + if (TEST(hi)) { FAST_TEST(hi); } + if (TEST(i)) { FAST_TEST(i); } + if (TEST(li)) { FAST_TEST(li); } + if (best) { + if (TEST(lli)) { FAST_TEST(lli); } + } else + best = 64; + fprintf(stderr, "int_fast%i_t = int%i_t\n\n", bits, best); + + return best; +} +#undef TEST + + +int main(int argc, char* argv[]) +{ + int r = 0; + if (argc < 2) + { + r |= printf("CHAR_BIT %zu\n", 8 * sizeof(char)); + r |= printf("SHORT_BIT %zu\n", 8 * sizeof(short int)); + r |= printf("INT_BIT %zu\n", 8 * sizeof(int)); + r |= printf("LONG_BIT %zu\n", 8 * sizeof(long int)); + r |= printf("LONG_LONG_BIT %zu\n", 8 * sizeof(long long int)); + r |= printf("PTR_BIT %zu\n", 8 * sizeof(void*)); + + r |= printf("INT%zu %s\n", 8 * sizeof(char), "char"); + r |= printf("INT%zu %s\n", 8 * sizeof(short int), "short int"); + r |= printf("INT%zu %s\n", 8 * sizeof(int), "int"); + r |= printf("INT%zu %s\n", 8 * sizeof(long int), "long int"); + r |= printf("INT%zu %s\n", 8 * sizeof(long long int), "long long int"); + return r < 0 ? 1 : 0; + } + else if (argc == 2) + { + if (!strcmp(argv[1], "fast8")) r = fast(8); + else if (!strcmp(argv[1], "fast16")) r = fast(16); + else if (!strcmp(argv[1], "fast32")) r = fast(32); + else if (!strcmp(argv[1], "fast64")) r = fast(64); + if (r <= 0) + return 1; + return printf("%i\n", r) < 0 ? 1 : 0; + } - return 0; + return 1; } diff --git a/gen/bits/intconf.h b/gen/bits/intconf.h index 2dca3b5..eb7b5b5 100644 --- a/gen/bits/intconf.h +++ b/gen/bits/intconf.h @@ -18,7 +18,11 @@ #ifndef _BITS_INTCONF_H #define _BITS_INTCONF_H //>set -e -//>FAST8=8; FAST16=64; FAST32=64; FAST64=64 + +//>FAST8=$(bin/gen/bits/intconf fast8) +//>FAST16=$(bin/gen/bits/intconf fast16) +//>FAST32=$(bin/gen/bits/intconf fast32) +//>FAST64=$(bin/gen/bits/intconf fast64) #define __MAX_TO_MIN(max) (-(max) - 1) #define __CHAR_BIT //(bin/gen/bits/intconf | grep ^CHAR_BIT | sed "s/^[^ ]* //") @@ -45,6 +49,5 @@ #define __UINT_FAST64_MAX UINT//{FAST64}_MAX - #endif |