【问题标题】:Type cast char array[16] to int 128 bits类型 cast char array[16] 到 int 128 位
【发布时间】:2014-12-19 13:12:51
【问题描述】:

我有两个 16 字节的 char 数组:

char word[WORD_LENGTH] = { '1', '2', '3', '4', '5', '6','7','8','9','0','1','2','3','4','5','\0'};
char word2[WORD_LENGTH] = { '1', '2', '3', '4', '5', '6','7','8','9','0','1','2','3','4','5','\0'};

我正在寻找一种比逐个字符比较更快地比较两个字符数组的方法。据我所知,我认为我可以使用类型转换将 char 数组转换为 128 int;像这样

__int128 value = (__int128) word;
__int128 value2 = (__int128) word2;

但是这些都不行,因为 value 和 value2 包含 word 和 word2 的地址。

如何将 char 数组转换为 __int128?

【问题讨论】:

  • 使用指针或联合,但仍然会有字节序问题
  • C 还是 C++?你知道它们是不同的语言,对吧?
  • 但是位的顺序无关紧要,我只想检查这两个单词是否相同。
  • 你试过memcmp吗?
  • @SHR 我认为类型转换比 memcmp 更快,因为是直接的。

标签: c++ c


【解决方案1】:

注意:您询问的是两种语言,并没有说明您实际使用的是哪种语言。我会尝试回答这两个问题,但是我对 C 的了解已经过时了几年,所以我可能会在其中弄错一些细节。

有多种选择;您必须测量它们以确定在您的环境中哪个速度最快。

std::equal(在 C++ 中)或 memcmp(在 C 中)的良好实现可能会针对已知大小的小数组进行优化。这可能已经足够了。

将字节重新解释为另一种类型的唯一明确定义的方法是复制它们:

__int128 value;
copy(begin(word), end(word), reinterpret_cast<char*>(&value));  // C++
memcpy((char*)(&value), word, WORD_SIZE)                        // C

编译器可能会也可能不会优化它以加载单词而不是字节。

如果一切都失败了,你可以诉诸正式未定义的行为:

__int128 value = *reinterpret_cast<__int128*>(word); // *(__int128*)word in C

在某些平台上,如果数组没有适当对齐或其他原因,这可能会失败。

【讨论】:

    【解决方案2】:

    我只会使用 memcmp。

    您确定您正在使用的编译器会在 cpu 的某个特殊部分比较 int128,在这些特殊部分可以比较 128 个整数吗? 因为如果它拆分成 32 位 pars,它将毫无用处。

    int memcmp(word, word2, 16)
    

    如果你正在寻找极端性能的案例,你必须比较从这个逻辑的不同实现派生的 ASM

    还要考虑 128 位数学在 mmx 或 sse 或 avx 的域中。据我所知,这些是用于同时用于多组数据的,我认为将它们用于单个比较在速度增益方面没有用。

    如果它在性能方面有用,我敢打赌 gcc、icc 和其他 c 编译器会做这个 128 位、256 位比较作为 memcmp 的内部优化,而不是将想法留给用户。

    【讨论】:

    • memcmp 在大多数编译器中都是用汇编语言实现的。
    • 当然,这就是我提出它的原因。 int128 是常见的吗?
    • 目前还不是很普遍,也许当 128 位操作系统会变得普遍。
    • memcmp 函数比 sse+type cast 慢,因为 sse 使用 128 位寄存器。但是,sse + 类型转换仅在数组对齐时运行。
    【解决方案3】:

    试试

    __int128 value = *(__int128 *)word;
    

    【讨论】:

    • 这是未定义的行为。
    • @AntonSavin:没错,但这可能会有所帮助,因为速度比可移植性更重要(当然,在检查编译器如何处理这个问题之后)。
    • 使用 __int128 可能已经超出了标准,所以是的,你当然要小心,但它可能是给定编译器的一个很好的解决方案。 (对您正在做的事情有适当的关心和了解)
    • 将字节数组(间接地,通过指针转换)转换为__int128 确实是未定义的行为。但 ISTM 这正是问题想要的。
    【解决方案4】:

    使用标准的比较函数memcmp,让编译器操心优化你的代码:

    memcmp(word, word2, WORD_LENGTH)
    

    如果在分析后发现这对您来说不够快,您可以考虑改进它(例如,通过使用联合,或使用 SSE2 内在函数)——但您很可能会发现很难击败一个好的实现memcmp.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      • 1970-01-01
      相关资源
      最近更新 更多