Abd*_*had 2 c++ assembly gcc inline-assembly built-in
考虑以下汇编代码循环:
#include <iostream>
#define ADD_LOOP(i, n, v) \
asm volatile ( \
"movw %1, %%cx ;" \
"movq %2, %%rax ;" \
"movq $0, %%rbx ;" \
"for: ;" \
"addq %%rax, %%rbx ;" \
"decw %%cx ;" \
"jnz for ;" \
"movq %%rbx, %0 ;" \
: "=x"(v) \
: "n"(i), "x"(n) \
: "%cx", "%rax", "%rbx" \
);
int main() {
uint16_t iter(10000);
uint64_t num(5);
uint64_t val;
ADD_LOOP(iter, num, val)
std::cout << val << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是否可以在循环内调用C函数(或它的机器代码输出),如上所述?
例如:
#include <wmmintrin.h>
int main() {
__m128i x, y;
for(int i = 0; i < 10; i++) {
x = __builtin_ia32_aesenc128(x, y);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
谢谢
Pet*_*des 10
不行.内置函数不是可以调用的实际函数call
.它们总是在C/C++中使用时内联.
例如,如果您想要int __builtin_popcount (unsigned int x)
获取popcnt
目标指令-mpopcnt
,或者为不支持该popcnt
指令的目标获取逐字节查找表,那么您就不走运了.您必须#ifdef
自己使用popcnt
或使用其他指令序列.
你在谈论的功能,__builtin_ia32_aesenc128
仅仅是一个包装的aesenc
汇编指令,你可以只如果汇编编写直接使用.
如果您正在编写asm而不是使用C++内在函数(就像#include <immintrin.h>
性能一样,您需要查看http://agner.org/optimize/以编写更高效的asm(例如,%ecx
用作循环计数器,而不是%cx
.你'使用16位部分寄存器不会获得任何好处.
您还可以编写更有效的inline-asm约束,例如movq %%rbx, %0
浪费指令.你可以使用%0
整个时间而不是显示%rbx
.如果你的内联asm以一个mov指令开始或结束来复制到输出/输入操作数,那么通常你做错了.让编译器为您分配寄存器.请参阅内联汇编标记wiki.
或者更好,https://gcc.gnu.org/wiki/DontUseInlineAsm.具有内在函数的代码通常可以很好地编译x86.请参阅英特尔的内在指南:#include <immintrin.h>
并使用__m128i _mm_aesenc_si128 (__m128i a, __m128i RoundKey)
.(在gcc中它只是一个包装器__builtin_ia32_aesenc128
,但它使你的代码可以移植到其他x86编译器.)
归档时间: |
|
查看次数: |
702 次 |
最近记录: |