标签: micro-optimization

使用内在函数提取和移位奇数/偶数位

有没有办法使用内在函数来优化以下代码?它获取 16 位整数中的所有奇数索引位,并将它们尽可能向右移动。

我在想也许可以使用 Fortran 中 IHFTC 的 C++ 等效项(是否有与此等效的 C++ 版本?)。但我觉得还有更有效的方法。

int x = some16bitInt;
x = x&0x5555;
int y = 0;
for (int i = 0; i < 8; i++)
    y = y | ((x >> i) & (0x01 << i));
'''
Run Code Online (Sandbox Code Playgroud)

c++ bit-manipulation intrinsics micro-optimization

3
推荐指数
1
解决办法
991
查看次数

为什么 clang 的尾声使用 `add $N, %rsp` 而不是 `mov %rbp, %rsp` 来恢复 `%rsp`?

考虑以下:

ammarfaizi2@integral:/tmp$ vi test.c
ammarfaizi2@integral:/tmp$ cat test.c

extern void use_buffer(void *buf);

void a_func(void)
{
    char buffer[4096];
    use_buffer(buffer);
}

__asm__("emit_mov_rbp_to_rsp:\n\tmovq %rbp, %rsp");

ammarfaizi2@integral:/tmp$ clang -Wall -Wextra -c -O3 -fno-omit-frame-pointer test.c -o test.o
ammarfaizi2@integral:/tmp$ objdump -d test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <emit_mov_rbp_to_rsp>:
   0: 48 89 ec              mov    %rbp,%rsp
   3: 66 2e 0f 1f 84 00 00  cs nopw 0x0(%rax,%rax,1)
   a: 00 00 00 
   d: 0f 1f 00              nopl   (%rax)

0000000000000010 <a_func>:
  10: 55                    push   %rbp
  11: 48 …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 clang micro-optimization

3
推荐指数
1
解决办法
288
查看次数

何时可以重用avx指令中的源寄存器

在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用?

例如:我想使用vgatherdps消耗两个 ymm 寄存器的指令,其中之一是位移索引。我意识到vgatherdps收集数据需要花费大量时间,因为数据的局部性较差。

位移索引寄存器是否会在指令执行期间被保留,或者我可以在后续指令中重用它而无需挂起管道?

assembly simd cpu-architecture avx micro-optimization

3
推荐指数
1
解决办法
503
查看次数

imul 然后 mov 与 mov 然后 imul - 有什么区别吗?

如果我编译以下 C++ 程序:

int baz(int x) { return x * x; }
Run Code Online (Sandbox Code Playgroud)

在 clang 15 中,我得到:

baz(int):
        mov     eax, edi
        imul    eax, edi
        ret
Run Code Online (Sandbox Code Playgroud)

而 gcc 12.2 给了我:

baz(int):
        imul    edi, edi
        mov     eax, edi
        ret
Run Code Online (Sandbox Code Playgroud)

(请参阅GodBolt

这两种实现是否完全等同,而只是任意选择的问题?如果它们不等价,它们的差异如何体现或影响我的程序?我的意思是,就 CPU 状态副作用、其他指令的延迟、内联期间的行为等而言。

c++ assembly x86-64 cpu-architecture micro-optimization

3
推荐指数
1
解决办法
142
查看次数

为什么 C++ 标准库不使用可能/不可能的属性?

在 Visual Studio 中阅读标准库算法的实现时,他们根本不使用[[likely]]/属性。[[unlikely]]对我来说,应该使用的教科书示例[[unlikely]]是例如std::find_if(...),微软已经这样实现:

// Note that some noise are removed from the code
template <class _InIt, class _Pr>
_InIt find_if(_InIt _First, const _InIt _Last, _Pr _Pred) {
    for (; _First != _Last; ++_First) {
        if (_Pred(*_First)) {
            break;
        }
    }
    return _First;
}
Run Code Online (Sandbox Code Playgroud)

如前所述,find_if(...)这是 if 子句的 true 分支不太可能的教科书示例,因为大多数情况下它会在谓词验证为 true 之前迭代几个元素,因此 [[unlikely]] 将是一个优化机会。Microsoft 没有[[unlikely]]在这里使用该属性有什么原因吗?

c++ algorithm micro-optimization compiler-optimization likely-unlikely

3
推荐指数
1
解决办法
182
查看次数

在Java中将网页内容读入字符串的最佳方法是什么?

我有以下Java代码来获取给定URL的HTML页面的全部内容.这可以以更有效的方式完成吗?欢迎任何改进.

public static String getHTML(final String url) throws IOException {
    if (url == null || url.length() == 0) {
        throw new IllegalArgumentException("url cannot be null or empty");
    }

    final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
    final BufferedReader buf = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    final StringBuilder page = new StringBuilder();
    final String lineEnd = System.getProperty("line.separator");
    String line;
    try {
        while (true) {
            line = buf.readLine();
            if (line == null) {
                break;
            }
            page.append(line).append(lineEnd);
        }
    } finally {
        buf.close();
    }

    return page.toString();
} …
Run Code Online (Sandbox Code Playgroud)

java string optimization inputstream micro-optimization

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

IF,CASE和WHILE语句之间有什么区别

我只是想知道objective-c中所有条件语句之间的区别是哪一个更快更轻.

objective-c micro-optimization conditional-statements

2
推荐指数
3
解决办法
1万
查看次数

具有潜在性能优化的浮点算法

对于大学讲座,我正在寻找具有已知渐近运行时的浮点算法,但是可以进行低级(微)优化.这意味着优化,例如最小化缓存未命中和寄存器溢出,最大化指令级并行性以及利用新CPU上的SIMD(向量)指令.优化将特定于CPU,并将使用适用的指令集扩展.

经典的教科书示例是矩阵乘法,通过简单地重新排序存储器访问序列(以及其他技巧)可以实现极大的加速.另一个例子是FFT.不幸的是,我不允许选择其中任何一个.

任何人有任何想法,或可以使用提升的算法/方法?

我只对可以想象每线程加速的算法感兴趣.通过多线程并行解决问题很好,但不是本讲座的范围.

编辑1:我的过程中,没有教它.在过去几年中,有不少项目在性能方面成功超越了当前最佳实施.

编辑2:本文列出了(从第11页开始)七类重要的数值方法和一些使用它们的相关算法.至少一些提到的算法是候选者,但是很难看出哪个算法.


编辑3:谢谢大家的好建议!我们建议实施曝光融合算法(2007年的论文),我们的提案被接受了.该算法创建类似HDR的图像,主要包括小核卷积,然后是源图像的加权多分辨率混合(在拉普拉斯金字塔上).我们感兴趣的是,该算法已经在广泛使用的Enfuse工具中实现,该工具现在的版本为4.1.因此,我们将能够验证和比较我们的结果与原始结果,也可能有助于工具本身的开发.如果可以的话,我将在未来更新这篇文章.

algorithm floating-point optimization performance micro-optimization

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

如何加快这种插入排序?(C中的内联汇编)

因此,此插入排序是用x86编写的,但嵌入在C中。它还具有一个标志,在对数组的一半进行排序后,我们将其设置为保留。有什么办法可以提高性能?

void asmInsSort(int *list, int arrayLen, int halfpoint) {
 _asm
 {

    mov ecx, arrayLen
    mov esi, list
    mov ebx, halfpoint
    mov eax, 0

    more:
        cmp ecx, 0              // Compare current arrayLen w/ 0
            je  done            // If it is equal, we are done
        mov edi, eax            //J = I
        push eax                //push eax (i) to free up register for key
        mov eax, [esi + edi]    //Key = Array[i] technically j
        sub edi, 4              //J - 1
        mov edx, arrayLen       //K …
Run Code Online (Sandbox Code Playgroud)

x86 assembly inline-assembly micro-optimization insertion-sort

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

程序集中的冗余值复制?

我正在从《Programming Ground Up》一书中学习x86汇编。在介绍函数时,作者给出了一个函数示例,该函数将给定的4字节整数提高为大于0的幂。这是函数的定义方式(这是我编写的版本,但是代码几乎相同):

 1. .type find_pow, @function
 2. find_pow:
 3. pushl %ebp          # Save current base pointer
 4. movl %esp, %ebp     # Copy stack pointer to base pointer
 5. movl $1, %eax        # %eax will hold the result, set it to 1
 6.
 7. subl $4, %esp
 8. movl 8(%ebp), %ebx
10. movl 12(%ebp), %ecx
11.
12. movl %ebx, -4(%ebp)
13.
14. loop_find_pow:      # Start loop
15. cmpl $1, %ecx        # If 2nd parameter equals 0
16. je …
Run Code Online (Sandbox Code Playgroud)

optimization x86 assembly micro-optimization

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