C++ 将单词拆分为两个字节的最快方法

C++ 将单词拆分为两个字节的最快方法,c++,c,performance,bit-manipulation,operation,C++,C,Performance,Bit Manipulation,Operation,那么,将一个单词拆分为两个字节的最快方法是什么 short s = 0x3210; char c1 = s >> 8; char c2 = s & 0x00ff; 对 short s = 0x3210; char c1 = s >> 8; char c2 = (s << 8) >> 8; 我99.9%确信,在几乎所有的体系结构中,第一个至少与第二个一样快。可能有一些架构没有区别(它们是相等的),而在一些架构中,后者会更慢 我想说第二个更

那么,将一个单词拆分为两个字节的最快方法是什么

short s = 0x3210;
char c1 = s >> 8;
char c2 = s & 0x00ff;

short s = 0x3210;
char c1 = s >> 8;
char c2 = (s << 8) >> 8;

我99.9%确信,在几乎所有的体系结构中,第一个至少与第二个一样快。可能有一些架构没有区别(它们是相等的),而在一些架构中,后者会更慢

我想说第二个更慢的主要原因是,有两个移位来产生
c2
数字。处理器在完成第一个班次之前无法开始处理第二个班次

同样,编译器也可以使用第一个编译程序来做其他聪明的事情(如果有这样做的指令——例如,x86处理器可以将
s
加载到AX中,并将AL存储到
c1
中,将AH存储到
c2
中——在存储操作之外没有额外的指令),第二个编译程序不太可能是“已知的通用模式”(我当然从未见过在代码中使用该变体,在代码中,
shift/和
方法非常常用-通常在“像素循环”中使用,这意味着对其进行良好的优化至关重要)


像往常一样,测量,测量,再测量。除非你只对你的特定机器的性能感兴趣,否则在不同型号/制造商的处理器上尝试一下,这样你就不会在你的机器上制造速度快5%的东西,而在另一个型号上制造速度慢20%的东西。

让编译器帮你完成这项工作。使用
union,其中字节将在不进行任何手动位移位的情况下拆分。请查看伪代码:

union U {
  short s;  // or use int16_t to be more specific
  //   vs.
  struct Byte {
    char c1, c2;  // or use int8_t to be more specific
  }
  byte;
};
用法很简单:

U u;
u.s = 0x3210;
std::cout << u.byte.c1 << " and " << u.byte.c2;
U;
u、 s=0x3210;

std::cout您当然应该使用强制转换,而不是掩码或两次移位来提取低阶字节。然后编译器将执行已知最快的任何操作。这就给您留下了高阶位,只有一个选择。

您应该在
中对每个位计时(长i=0;i<100000000;i++)
。我做了,速度更快的是第一个(0.82秒对0.84秒)。在MVS中这样做的一个简单方法是在
@clk

上设置一个手表,每一个都做几百万次,然后计时。你试过第二个吗?我的第一个猜测是它不起作用(即使它起作用,它也是高度平台特定的)。那你为什么还要关心ZOMG最快的方式呢?移位和掩码不仅非常清晰和明显,而且也不太可能成为你的瓶颈。生成汇编代码,根据指令的数量亲自查看,或者将这些语句复制到大量,并有效地使用计时功能使用struct而不是char ch[2]?@Saksham,在这种情况下没有优势;而是使用
char c[2]
是一种更好的方法。我只是在一般情况下举了一个例子。通常我使用整数类型与具有各种位字段的结构,这将匹配整数大小。@Jonas,不要这样做。不建议使用这种C样式的类型转换,它被认为是丑陋的。没有类型转换,它将导致编译器错误(这是出于正确的理由)追求便携的做事方式。
U u;
u.s = 0x3210;
std::cout << u.byte.c1 << " and " << u.byte.c2;