在 x86_64 中,没有 64 位地址的直接跳转。只有一个 32 位的。通过间接跳转,我理解在分支预测发挥作用之前必须解决管道一次。我的问题是:在 64 位中没有办法在第一次执行时进行 1-3 个周期的跳转吗?
如何编写一个函数,将给定数量的字节从给定的源复制到 AARCH64 汇编语言的给定目的地?这基本上就像 memcpy,但有一些额外的假设。
到目前为止,我找到的最好的资源是memcpy 的源代码,但我不明白哪些部分与我给出的特定参数相关。
编辑:到目前为止,我已经尝试将 C 中的以下函数转换为程序集。
void memcpy80(unsigned char* dest, unsigned char* sourc, unsigned long count)
{
unsigned char* end = sourc + count;
while (sourc < end)
*(dest++) = *(sourc++)
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试将其归结为符合规范的版本,如下所示:
memcpy80:
add x3, x1, x2
loopstart:
cmp x3, x1
//how do I branch to loopend if x1 > x3?
add x0, x0, 1
add x1, x1, 1
ldr x4, [x1]
str x4, [x0]
b …Run Code Online (Sandbox Code Playgroud) 因此,我目前正在研究按位运算符和位操作,并且遇到了两种不同的方法将四个 1 字节字组合成一个 4 字节宽字。
下面给出了两种方式
找到这两种方法后,我比较了两者生成的反汇编代码(使用带 -O2 标志的 gcc 11 编译),我没有反汇编及其生成的代码的基本知识,我只知道代码越短,函数速度越快(大多数时候我猜......也许有一些例外),现在对于这两种方法来说,它们在生成的反汇编代码中似乎具有相同的行数/行数,所以我猜他们的表现是一样的?
我也对指令的顺序感到好奇,第一种方法似乎交替其他指令sal>or>sal>or>sal>or,而第二种方法更统一,sal>sal>sal>or>or>mov>or这对性能是否有一些重大影响,例如,如果我们正在处理更大的单词?
两种方法
int method1(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
int combine = 0;
combine = byte4;
combine <<=8;
combine |= byte3;
combine <<=8;
combine |= byte2;
combine <<=8;
combine |= byte1;
return combine;
}
int method2(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
int combine = 0, temp;
temp = byte4;
temp …Run Code Online (Sandbox Code Playgroud) 一个std::string_view参数比const char*下面代码中的一个参数更好吗?
void func( const std::string_view str )
{
std::istringstream iss( str.data( ) ); // str is passed to the ctor of istringstream
std::size_t pos { };
int num { std::stoi( str.data( ), &pos, 10 ) }; // and here it's passed to std::stoi
}
int main()
{
std::array<char, 20> buffer { };
std::cin.getline( buffer.data( ), 20 );
func( buffer.data( ) );
}
Run Code Online (Sandbox Code Playgroud)
std::istringstreamctor 和都std::stoi需要 aconst std::string&作为参数。但我std::string_view使用其data()成员函数向他们传递一个对象。这是不好的做法吗?我应该回到 …
我正在用 c 语言编写一个国际象棋引擎,速度至关重要。国际象棋引擎基于 unsigned long long,我将其表示为 u64,并且它严重依赖于最低有效位扫描。到目前为止,我一直在使用 gcc 函数 __builtin_ctzll ,它做得很好。然而,我使用 gcc -S -O2 为这个独立函数生成了汇编代码。它给了我以下内容:
xorl %eax, %eax
rep bsfq %rdi, %rax
cltq
ret
Run Code Online (Sandbox Code Playgroud)
然而经过一番调查似乎代码
rep bsfq %rdi, %rax
ret
Run Code Online (Sandbox Code Playgroud)
在我的国际象棋程序中做了完全相同的事情。然而现在速度慢了约 20%。它应该更快,因为它的指令更少。然而,原始的 __builtin_ctzll 内联在我的 C 代码中。这是我的自定义汇编代码运行速度比原始代码慢的原因吗?因为当我声明函数 ctzll 时,我当然不能在 c 中内联声明它,除非我有定义(不在汇编代码中)。
是否有另一种方法来优化汇编指令,或者我应该尝试直接在 c 中内联 asm 的新汇编代码?
我想只使用位操作来连接两个整数,因为我需要尽可能多的效率.有各种答案可用,但它们不够快我想要的是只使用左移位等操作的实现.请指导我怎么做
例
int x=32;
int y=12;
int result=3212;
Run Code Online (Sandbox Code Playgroud)
我正在和FPGA实现AES.我需要在我的系统上使用它来减少某些任务的时间消耗
c algorithm bit-manipulation concatenation micro-optimization
我有一个微观优化问题。我有 3 种处理 typed-Pointer(array) 的方法。哪一个更好?
for I:=0 to ArrCount-1 do
begin // I:Var is unused in below-block
Inc(P) ; // P is typed-Pointer
// do somethings
end;
Run Code Online (Sandbox Code Playgroud)
for I:=ArrCount-1 downto 0 do
begin // I:Var is unused in below-block
Inc(P) ; // P is typed-Pointer
// do somethings
end;
Run Code Online (Sandbox Code Playgroud)
While ArrCount>0 do
begin
Inc(P) ; // P is typed-Pointer
// do somethings
Dec(ArrCount);
end;
Run Code Online (Sandbox Code Playgroud) 我有memchr我要使非分支的这段代码:
.globl memchr
memchr:
mov %rdx, %rcx
mov %sil, %al
cld
repne scasb
lea -1(%rdi), %rax
test %rcx, %rcx
cmove %rcx, %rax
ret
Run Code Online (Sandbox Code Playgroud)
我不确定是否cmove是分支指令。是吗?如果是这样,如何重新排列我的代码,使其不分支?
assembly x86-64 cpu-architecture micro-optimization branch-prediction
我有两个逻辑上等效的函数:
long ipow1(int base, int exp) {
// HISTORICAL NOTE:
// This wasn't here in the original question, I edited it in,
if (exp == 0) return 1;
long result = 1;
while (exp > 1) {
if (exp & 1) result *= base;
exp >>= 1;
base *= base;
}
return result * base;
}
long ipow2(int base, int exp) {
long result = 1;
while (exp) {
if (exp & 1) result *= base;
exp >>= …Run Code Online (Sandbox Code Playgroud) 我正在尝试对代码进行微优化,我想知道将变量转换为布尔值哪个更快:
<?php
$a='test';
$result1 = !!$a;
$result2 = (bool)$a;
?>
Run Code Online (Sandbox Code Playgroud)
我不担心代码大小,只担心执行时间。
这里有一些基准,但它非常不确定(尝试了多次),所以我想知道 PHP 的源代码中会发生什么,看看它们是否有不同的处理方式:
<?php
$a = 'test';
for($c=0;$c<3;$c++){
$start = microtime(true);
for($i=0;$i<10000000;$i++){
$result = !!$a;
}
$end = microtime(true);
$delta = $end-$start;
echo '!!: '.$delta.'<br />';
}
$a = 'test';
for($c=0;$c<3;$c++){
$start = microtime(true);
for($i=0;$i<10000000;$i++){
$result = (bool)$a;
}
$end = microtime(true);
$delta = $end-$start;
echo '(bool): '.$delta.'<br />';
}
Run Code Online (Sandbox Code Playgroud)
结果
!!: 0.349671030045
!!: 0.362552021027
!!: 0.351779937744
(bool): 0.346690893173
(bool): 0.36114192009
(bool): 0.373970985413
Run Code Online (Sandbox Code Playgroud)