是否有一种高性能的方法来制作56位整数?

时间:2018-06-10 05:47:13

标签: c++11 optimization bit-manipulation

我正在编写一个具有8位操作码的虚拟机,其中一种常见的指令类型是8位操作码,后面是56位有符号整数操作数。

最初,我打算按如下方式实施这条指令:

struct machine_op {
   std::uint64_t opcode:8
   std::int64_t operand:56;
};

然而,我听到没有结束使用像这样的位域不可移植的评论,特别是,它不能保证操作数字段实际上在内存中的正确位置(即内存的第一个字节)结构)。

我当时想到的是创建一个56位整数类,并将上述结构修改为:

struct machine_op {
   char opcode;
   int56 operand;
};

由于是标准的布局结构,只要int56以没有任何对齐限制的方式编写,就可以保证操作数的地址紧跟在操作码之后。

为此,我定义了以下类,其目的是封装一个没有对齐限制的带符号的56位整数:

class int56 {
public:
    struct data {
        unsigned char byte1;
        unsigned char byte2;
        unsigned char byte3;
        unsigned char byte4;
        unsigned char byte5;
        unsigned char byte6;
        unsigned char byte7;
    };

    struct big_endian {
        char sign;
        data value;
        inline big_endian() = default;

        inline constexpr big_endian(const data &v) : sign(v.byte1 & 0x80 ? 0xff : 0), value(v)
        {
        }
    };

    struct little_endian {
        data value;
        char sign;
        inline little_endian() = default;

        inline constexpr little_endian(const data &v) : value(v), sign(v.byte7 & 0x80 ? 0xff : 0)
        {
        }
    };

    union aligner {
        std::int64_t value;
        big_endian big;
        little_endian little;
    };
    inline int56() = default;

    inline constexpr int56(std::int64_t x) :
#if BYTE_ORDER == LITTLE_ENDIAN
    value((aligner{x}).little.value)
#else
    value((aligner{x}).big.value)
#endif
    {
    }

    inline constexpr operator std::int64_t() const 
    {
#if BYTE_ORDER == LITTLE_ENDIAN
        return (aligner{.little = little_endian(value)}).value;
#else
        return (aligner{.big = big_endian(value)}).value;
#endif
    }

private:
    data value;
};

此实现仅适用于大端或小端机器,但是...整数的其他位表示将失败。尽管如此,我仍然可以忍受这个限制,但即使使用高优化编译器标志,我发现访问这个类比使用位域有明显的性能损失。

顺便说一下,我总是要定位至少具有64位架构的机器,因此访问64位宽的数据是没有问题的。我只是不能求助于手工装配,因为除了使这些功能不再是constexpr之外,我还必须为每个支持的cpu架构编写程序集,而且我只能特别流利地使用其中一个。

这是合理的我能做的最好的,还是有更好的方法来设置这个int56类?

或者,有什么方法可以确保我能够使用位域来做我真正需要的事情吗?

提前致谢

0 个答案:

没有答案