标签: micro-optimization

64 位跳转的成本,第一次总是 10-22 个周期?

在 x86_64 中,没有 64 位地址的直接跳转。只有一个 32 位的。通过间接跳转,我理解在分支预测发挥作用之前必须解决管道一次。我的问题是:在 64 位中没有办法在第一次执行时进行 1-3 个周期的跳转吗?

x86 x86-64 micro-optimization

0
推荐指数
1
解决办法
508
查看次数

使用AARCH64程序集编写memcpy

如何编写一个函数,将给定数量的字节从给定的源复制到 AARCH64 汇编语言的给定目的地?这基本上就像 memcpy,但有一些额外的假设。

  1. 源和目标在 16 字节边界上对齐
  2. 内存区域不重叠
  3. 计数是16的倍数
  4. 指令必须在 80 字节以内

到目前为止,我找到的最好的资源是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)

assembly memcpy micro-optimization arm64

0
推荐指数
1
解决办法
2819
查看次数

将四个 1 字节变量连接成一个 4 字节字时,哪种移位和 OR 方法更快?(比较生成的汇编代码)

因此,我目前正在研究按位运算符和位操作,并且遇到了两种不同的方法将四个 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)

c x86 assembly bit-manipulation micro-optimization

0
推荐指数
1
解决办法
488
查看次数

string_view 与 const char* 性能

一个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++ c-strings stdstring micro-optimization string-view

0
推荐指数
1
解决办法
831
查看次数

C 中的内联汇编

我正在用 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 的新汇编代码?

c assembly gcc x86-64 micro-optimization

0
推荐指数
1
解决办法
374
查看次数

使用位操作的两个整数的十进制级联

我想只使用位操作来连接两个整数,因为我需要尽可能多的效率.有各种答案可用,但它们不够快我想要的是只使用左移位等操作的实现.请指导我怎么做

int x=32;
int y=12;
int result=3212;
Run Code Online (Sandbox Code Playgroud)

我正在和FPGA实现AES.我需要在我的系统上使用它来减少某些任务的时间消耗

c algorithm bit-manipulation concatenation micro-optimization

-1
推荐指数
2
解决办法
1347
查看次数

Delphi中的for循环(downto,Reversed)与for循环(递增模式)与while循环

我有一个微观优化问题。我有 3 种处理 typed-Pointer(array) 的方法。哪一个更好?

1

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)

2

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)

3

While ArrCount>0 do
begin  
  Inc(P) ; // P is typed-Pointer
  
  // do somethings 
  Dec(ArrCount);
end;
Run Code Online (Sandbox Code Playgroud)

delphi micro-optimization

-1
推荐指数
1
解决办法
2596
查看次数

CMOVcc是否被视为分支指令?

我有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

-1
推荐指数
1
解决办法
128
查看次数

而(n> 1)比while(n)快25%?

我有两个逻辑上等效的函数:

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)

c performance gcc micro-optimization

-2
推荐指数
1
解决办法
858
查看次数

PHP 中哪个更快:!!或(布尔)?

我正在尝试对代码进行微优化,我想知道将变量转换为布尔值哪个更快:

<?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)

php boolean micro-optimization

-2
推荐指数
1
解决办法
228
查看次数