特別困っているわけではないのですが、気になったので質問です。

int_fast16_t/int_fast32_tの実態がWindowsとLinuxで異なっているのですが、x64では32ビット整数と64ビット整数の演算はどちらが高速なのでしょうか?
(Wikipediaの注釈5にある資料がどういう比較なのか理解できていません。)

             | Linux(64)      | Windows(64)    | FreeBSD(64)
-------------+----------------+----------------+-------------
int_fast8_t  | signed char(8) | signed char(8) | int(32)
int_fast16_t | long(64)       | int(32)        | int(32)
int_fast32_t | long(64)       | int(32)        | int(32)
int_fast64_t | long(64)       | long long(64)  | long(64)

以下、int_fastN_tの実態を調査したプログラムです。

#include <climits>
#include <cstdint>
#include <type_traits>

#include <iostream>
#include <sstream>

using namespace std;

#define PRINT_SAME_TYPE(d_type) \
    do { \
        ostringstream ostream; \
        ostream << #d_type << " = "; \
        if ( is_same<d_type, signed char>::value ) { \
            ostream << "signed char(" << CHAR_BIT << ")"; \
        } \
        else if ( is_same<d_type, short>::value ) { \
            ostream << "short(" << sizeof(short) * CHAR_BIT << ")"; \
        } \
        else if ( is_same<d_type, int>::value ) { \
            ostream << "int(" << sizeof(int) * CHAR_BIT << ")"; \
        } \
        else if ( is_same<d_type, long>::value ) { \
            ostream << "long(" << sizeof(long) * CHAR_BIT << ")"; \
        } \
        else if ( is_same<d_type, long long>::value ) { \
            ostream << "long long(" << sizeof(long long) * CHAR_BIT << ")"; \
        } \
        else { \
            ostream << "unknown"; \
        } \
        cout << ostream.str() << '\n'; \
    } while ( false )

int main()
{
    cout << "sizeof(char) = " << CHAR_BIT << '\n';
    cout << "sizeof(short) = " << sizeof(short) * CHAR_BIT << '\n';
    cout << "sizeof(int) = " << sizeof(int) * CHAR_BIT << '\n';
    cout << "sizeof(long) = " << sizeof(long) * CHAR_BIT << '\n';
    cout << "sizeof(long long) = " << sizeof(long long) * CHAR_BIT << '\n';
    cout << "sizeof(void *) = " << sizeof(void *) * CHAR_BIT << '\n';

    PRINT_SAME_TYPE(int_fast8_t);
    PRINT_SAME_TYPE(int_fast16_t);
    PRINT_SAME_TYPE(int_fast32_t);
    PRINT_SAME_TYPE(int_fast64_t);

    PRINT_SAME_TYPE(int_least8_t);
    PRINT_SAME_TYPE(int_least16_t);
    PRINT_SAME_TYPE(int_least32_t);
    PRINT_SAME_TYPE(int_least64_t);
}

Linux(64)での実行結果:

sizeof(char) = 8
sizeof(short) = 16
sizeof(int) = 32
sizeof(long) = 64
sizeof(long long) = 64
sizeof(void *) = 64
int_fast8_t = signed char(8)
int_fast16_t = long(64)
int_fast32_t = long(64)
int_fast64_t = long(64)
int_least8_t = signed char(8)
int_least16_t = short(16)
int_least32_t = int(32)
int_least64_t = long(64)

Windows(64)での実行結果:

sizeof(char) = 8
sizeof(short) = 16
sizeof(int) = 32
sizeof(long) = 32
sizeof(long long) = 64
sizeof(void *) = 64
int_fast8_t = signed char(8)
int_fast16_t = int(32)
int_fast32_t = int(32)
int_fast64_t = long long(64)
int_least8_t = signed char(8)
int_least16_t = short(16)
int_least32_t = int(32)
int_least64_t = long long(64)

16ビット以上あれば良い整数は長らくint型を使ってきましたが、64ビットマシン時代になってint型が「そのマシンでのワードの自然な大きさ」ではなくなってしまったようなので、これからはint型の代わりに何を使おうかなぁとふと思いまして。


Linuxと同じくLP64モデルを採用しているFreeBSDを調べてみると、LinuxともWindowsとも異なる結果でした。データモデルとは関係なさそうです。

FreeBSD(64)での実行結果:

sizeof(char) = 8
sizeof(short) = 16
sizeof(int) = 32
sizeof(long) = 64
sizeof(long long) = 64
sizeof(void *) = 64
int_fast8_t = int(32)
int_fast16_t = int(32)
int_fast32_t = int(32)
int_fast64_t = long(64)
int_least8_t = signed char(8)
int_least16_t = short(16)
int_least32_t = int(32)
int_least64_t = long(64)