- #include <stdio.h>
- #include <stdint.h>
- #include <inttypes.h>
- int
- main ()
- {
- uint_least16_t p,x;
- int count;
- p = 1;
- for (count = 100000; count != 0; --count)
- for (x = 1; x != 50000; ++x)
- p*= x;
- printf("%"PRIuLEAST16,p);
- return 0;
- }
在程序上运行time命令,我明白了
- real 0m7.606s
- user 0m7.557s
- sys 0m0.019s
如果我将类型更改为uint_fast16_t(和printf修饰符),则时间变为
- real 0m12.609s
- user 0m12.593s
- sys 0m0.009s
那么,如果stdint.h头文件将uint_fast16_t(以及uint_fast32_t)定义为4字节类型,那会不会更好?
所以问题是:这里真的是GCC定义uint_fast16_t,还是实际上是Linux(我的意思是这里的内核),甚至可能是标准C Lib(大多数情况下是glibc),它定义了那些类型?因为如果Linux或glibc定义了这些,那么建立在该系统上的GCC除了采用它们已经建立的任何约定之外别无选择.对于所有其他可变宽度类型也是如此:char,short,int,long,long long;所有这些类型在C标准中只有最小保证位宽(对于int,它实际上是16位,因此在int为32位的平台上,它已经比标准要求的大得多).
除此之外,我实际上想知道你的cpu /编译器/系统有什么问题.在我的系统上,64位乘法与32位乘法同样快.我修改了你的代码来测试16位,32位和64位:
- #include <time.h>
- #include <stdio.h>
- #include <inttypes.h>
- #define RUNS 100000
- #define TEST(type) \
- static type test ## type () \
- { \
- int count; \
- type p,x; \
- \
- p = 1; \
- for (count = RUNS; count != 0; count--) { \
- for (x = 1; x != 50000; x++) { \
- p *= x; \
- } \
- } \
- return p; \
- }
- TEST(uint16_t)
- TEST(uint32_t)
- TEST(uint64_t)
- #define CLOCK_TO_SEC(clock) ((double)clockTime / CLOCKS_PER_SEC)
- #define RUN_TEST(type) \
- { \
- clock_t clockTime; \
- unsigned long long result; \
- \
- clockTime = clock(); \
- result = test ## type (); \
- clockTime = clock() - clockTime; \
- printf("Test %s took %2.4f s. (%llu)\n",\
- #type,CLOCK_TO_SEC(clockTime),result \
- ); \
- }
- int main ()
- {
- RUN_TEST(uint16_t)
- RUN_TEST(uint32_t)
- RUN_TEST(uint64_t)
- return 0;
- }
使用未经优化的代码(-O0),我得到:
- Test uint16_t took 13.6286 s. (0)
- Test uint32_t took 12.5881 s. (0)
- Test uint64_t took 12.6006 s. (0)
使用优化代码(-O3),我得到:
- Test uint16_t took 13.6385 s. (0)
- Test uint32_t took 4.5455 s. (0)
- Test uint64_t took 4.5382 s. (0)
On x86_64,32-bit arithmetic should never be slower than 64-bit
arithmetic,period.
第二个输出显示32/16位算术不能说同样的事情.即使我的x86 cpu本身可以执行16位运算,32位算术在32/64位cpu上也会明显变慢.与其他一些cpu不同,例如PPC,它只能执行32位算术.但是,这似乎只适用于我的cpu上的乘法,当更改代码进行加/减/除时,16和32位之间没有显着差异.
以上结果来自英特尔酷睿i7(2.66 GHz),但如果有人感兴趣,我也可以在英特尔酷睿2双核处理器(旧一代cpu)和摩托罗拉PowerPC G4上运行此基准测试.