【问题标题】:C++: the fastest way to access specific octet of intC ++:访问特定八位字节的最快方法 int
【发布时间】:2012-03-14 17:49:00
【问题描述】:

假设我们有 32 位整数、8 位字符、gcc 编译器和 Intel 架构:

提取整数变量的第三个八位字节的最快方法是什么(不使用汇编程序)?例如,将其存储到 char[] 某个特定位置的 char 中?

【问题讨论】:

  • 别管“最快”;你知道怎么做吗?然后这样做,让编译器对其进行优化。
  • 使用最明显的方式,让编译器转换成更高效的方式?例如。 (some_integer>>16)&0xff.
  • 为什么你认为你需要最快的方式来进行这样的操作?您在此操作中是否存在性能瓶颈?除了显而易见的事情之外,做其他事情还有什么意义吗?
  • 似乎只有两种远程明智的方法:(char) (i >> 16),正如 arc 所建议的那样,以及 ((char*)&i)[2]。 (后者也可以通过union 完成。)我猜前者通常更快(没有指针运算,不需要i 有内存位置),但为什么不尝试两种方式,看看哪个在您的程序中运行得更快?
  • @DavidRodríguez-dribeas 联合技巧是形式上未定义的行为(尽管我从未听说过不能工作的编译器)。另一方面,它和指针转换都非常依赖于架构,并且在不同的机器上会有不同的语义。

标签: c++ optimization micro-optimization


【解决方案1】:

对于第 3 个八位字节(小端序):

int i = 0xdeadbeef;
char c = (char) (i>>16); // c = 0xad

【讨论】:

    【解决方案2】:

    使用 Union

    union myCharredInt
    {
        int myInt;
        struct {
            char char1;
            char char2;
            char char3;
            char char4;
        }
    };
    
    myCharredInt a = 5;
    
    char c = a.char3;
    

    【讨论】:

    • 这不能保证有效,因为编译器可以在结构成员之间添加填充。
    • 匿名结构是微软的扩展。 GCC 真的支持它吗?在 C++ 中以这种方式使用联合也是未定义的行为。
    • 另外,int 的位不能保证按此顺序排列。 (大端与小端)。真正的程序员从 0 开始计数 ;)
    • 不保证 int 以任何顺序放置。但是字符是。第三个字符将是内存中的第三个聊天。 OP想要那个,所以我猜他知道布局。无论如何,从 0 开始计数只是为了表示从一开始的偏移量而发明的一个概念。你并没有真正用它来计算。
    • 以这种方式使用联合不是该语言所必需或定义的,它几乎可以在我尝试过的任何编译器上工作,但我已经指出并为自己确认了它不保证能正常工作。
    【解决方案3】:

    将八位字节移到最不重要的八位字节并存储它

    有点像这样,但这取决于你所说的第 3 个八位字节是什么意思,因为我的大部分经验都是在大端架构中

    char *ptr;
    ....
    *ptr = val >> 8;
    

    【讨论】:

    • 如果使用位移,字节序无关紧要。如果您将整数转换为 char 指针并直接访问字节,那么这很重要。
    • @AndréCaron:从提出问题的方式来看,我认为情况正好相反:如果您直接访问字节,那么“第三个八位字节”始终是第三个字节,但如果您是使用位移,那么您需要知道第三个八位字节是第二重要的(如在小端架构上)还是第三重要的(如在大端架构上)。
    【解决方案4】:

    当您在非常特殊的情况下寻找“最快”或“最好”的方法来做某事时,答案几乎总是:实验并找出答案。

    虽然有一些经验法则可供遵循,但它们不会最终为您提供针对您的特定系统、架构、编译器等的最佳答案。

    您会注意到,您的问题已经有几个不同的答案,使用不同的技术。

    你怎么知道哪个最好?

    答案:试一试。分析他们。

    N.b.:我有点开玩笑。我怀疑你真正想知道的是如何做到这一点,而不是如何最快地做到这一点。

    【讨论】:

    • 我如何描述我什至不知道的东西?如果我什至不知道前者的存在,我将如何比较“联合技巧”与“移位和掩码”的速度?为什么我要问这个问题意味着我不是这个意思?你和其他许多人在这个话题上的反应是毫无意义的咄咄逼人和无知,这在 SO 上令人惊讶。
    • @izhak:这种行为是对两种现象的回应:1)太多的程序员过度关注微优化;和 2) 这么多关于 SO 优化的实际上不合理的问题。除非您描述需要这样做的特定场景(例如,“我正在编写视频编解码器并在紧密循环中每秒运行 10^6 次这些东西......”)以及到目前为止您提出的任何解决方案,那么这个问题就没有真正的答案。真正的答案取决于您的编译器和硬件,我们没有什么可作为基准的。
    • @izhak:有一个问题我想以链接为例,但我找不到了。
    • @AndréCaron:编译器和硬件与其他信息一起在问题的第一行中指定。我的问题真的很幸运地描述了对我来说似乎无关紧要的问题。我从来不知道这会成为一个问题。稍后我将使用基准测试结果更新问题。
    • @izhak:严格来说,问题是“做 X 的最快方法”,而不是“如何做 X”。我以为我在最后一行中明确了这种区别。如果您想知道如何操作,请参阅其他很好的答案。如果您想知道在您的特定情况下如何最好地做到这一点,请参阅我的回答。不过,我很抱歉表现得咄咄逼人。我真的觉得我在回答所提出的问题,尽管是一眨眼的油嘴滑舌。
    猜你喜欢
    • 2015-01-17
    • 2011-10-19
    • 2014-03-27
    • 2012-02-08
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多