gpt4 book ai didi

c++ - 将 GCC 内联汇编 CMOV 转换为 Visual Studio 汇编器

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:09:37 26 4
gpt4 key购买 nike

文章中Linear vs. Binary Search ,有一个使用 CMOV 指令的二进制搜索的快速实现。我想在 VC++ 中实现它,因为我正在处理的应用程序依赖于二进制搜索的性能。

enter image description here

该实现有一些 GCC 内联汇编器,声明如下:

static int binary_cmov (const int *arr, int n, int key) {
int min = 0, max = n;
while (min < max) {
int middle = (min + max) >> 1;

asm ("cmpl %3, %2\n\tcmovg %4, %0\n\tcmovle %5, %1"
: "+r" (min),
"+r" (max)
: "r" (key), "g" (arr [middle]),
"g" (middle + 1), "g" (middle));

// Equivalent to
// if (key > arr [middle])
// min = middle + 1;
// else
// max = middle;
}
return min;
}

我想将此 GCC 汇编程序转换为 Microsoft Visual Studio 兼容的汇编程序,但作为 GCC 新手不知道从哪里开始。

任何人都可以提供帮助,或者至少解释一下 GCC 内联汇编器吗? TIA!

最佳答案

重构代码以更好地向编译器表达意图:

int binary_cmov (const int *arr, int n, int key) 
{
int min = 0, max = n;
while (min < max)
{
int middle = (min + max) >> 1;
min = key > arr[middle] ? middle + 1 : min;
max = key > arr[middle] ? max : middle;
}
return min;
}

使用 gcc5.3 -O3,产量:

binary_cmov(int const*, int, int):
xorl %eax, %eax
testl %esi, %esi
jle .L4
.L3:
leal (%rax,%rsi), %ecx
sarl %ecx
movslq %ecx, %r8
leal 1(%rcx), %r9d
movl (%rdi,%r8,4), %r8d
cmpl %edx, %r8d
cmovl %r9d, %eax
cmovge %ecx, %esi
cmpl %eax, %esi
jg .L3
rep ret
.L4:
rep ret

故事的寓意——不要嵌入汇编程序。您所做的就是使代码不可移植。

更进一步...

为什么不更明确地表达意图?

#include <utility>

template<class...Ts>
auto sum(Ts...ts)
{
std::common_type_t<Ts...> result = 0;
using expand = int[];
void(expand{ 0, ((result += ts), 0)... });
return result;
}

template<class...Ts>
auto average(Ts...ts)
{
return sum(ts...) / sizeof...(Ts);
}

int binary_cmov (const int *arr, int n, int key)
{
int min = 0, max = n;
while (min < max)
{
int middle = average(min, max);
auto greater = key > arr[middle];
min = greater ? middle + 1 : min;
max = greater ? max : middle;
}
return min;
}

编译器输出:

binary_cmov(int const*, int, int):
xorl %eax, %eax
testl %esi, %esi
jle .L4
.L3:
leal (%rax,%rsi), %ecx
movslq %ecx, %rcx
shrq %rcx
movslq %ecx, %r8
leal 1(%rcx), %r9d
movl (%rdi,%r8,4), %r8d
cmpl %edx, %r8d
cmovl %r9d, %eax
cmovge %ecx, %esi
cmpl %eax, %esi
jg .L3
rep ret
.L4:
rep ret

关于c++ - 将 GCC 内联汇编 CMOV 转换为 Visual Studio 汇编器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37778784/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com