标签: micro-optimization

理解 `_mm_prefetch`

答案_mm_prefetch() 局部性提示是什么?详细说明提示的含义。

\n

我的问题是:我想要哪一个

\n

我正在研究一个被重复调用数十亿次的函数,其中一些int参数。我做的第一件事是使用该参数(其低 32 位)作为 4GB 缓存的键来查找一些缓存值。根据调用该函数的算法,我知道该密钥通常会从一次调用到下一次调用加倍(左移 1 位),所以我这样做:

\n
int foo(int key) {\n  uint8_t value = cache[key];\n  _mm_prefetch((const char *)&cache[key * 2], _MM_HINT_T2);\n  // ...\n
Run Code Online (Sandbox Code Playgroud)\n

目标是拥有这个value在下次调用该函数时将其放入处理器缓存中。

\n

我正在寻找对我对两点的理解的确认:

\n
    \n
  1. 致电给_mm_prefetch不会延迟紧随其后的指令的处理。
  2. \n
  3. 预取错误的位置不会受到任何惩罚,只是因为猜测正确而失去了好处。
  4. \n
\n

该函数使用 128 128 位值(总共 2 KB)的查找表。有没有办法 \xe2\x80\x9cforce\xe2\x80\x9d 它被缓存?该查找表的索引按顺序递增;我也应该预取它们吗?我可能应该使用另一个提示来指向另一个级别的缓存?这里最好的策略是什么?

\n

c++ performance prefetch intrinsics micro-optimization

4
推荐指数
1
解决办法
3243
查看次数

将 rax 寄存器的最高位设置为 rdx 寄存器中的最低位的最快方法

这是我的方法:

and rdx, 0x1
ror rdx, 1
or rax, rdx
Run Code Online (Sandbox Code Playgroud)

但我认为这不是很有效率。我不知道轮班操作是否会更具成本效益。

optimization assembly bit-manipulation x86-64 micro-optimization

4
推荐指数
1
解决办法
313
查看次数

使用 LEA 相对于 MOV 在从 C++ 编译的程序集中传递参数的优势

我正在尝试编译 C++ 代码时将参数传递给函数的方式。我尝试使用x64 msvc 19.35/latest编译器编译以下 C++ 代码以查看生成的程序集:

#include <cstdint>

void f(std::uint32_t, std::uint32_t, std::uint32_t, std::uint32_t);

void test()
{
    f(1, 2, 3, 4);
}
Run Code Online (Sandbox Code Playgroud)

并得到这个结果:

void test(void) PROC
        mov     edx, 2
        lea     r9d, QWORD PTR [rdx+2]
        lea     r8d, QWORD PTR [rdx+1]
        lea     ecx, QWORD PTR [rdx-1]
        jmp     void f(unsigned int,unsigned int,unsigned int,unsigned int)
void test(void) ENDP
Run Code Online (Sandbox Code Playgroud)

godbolt.org 上的结果

我不明白的是,为什么编译器在这个例子中选择使用lea而不是简单的。mov我了解它的机制lea以及它如何在每个寄存器中产生正确的值,但我希望有更简单的东西,例如:

void test(void) PROC
        mov     ecx, 1
        mov     edx, 2
        mov     r8d, 3
        mov     r9d, 4 …
Run Code Online (Sandbox Code Playgroud)

c++ assembly x86-64 micro-optimization visual-c++

4
推荐指数
2
解决办法
182
查看次数

Python if else微优化

在思考代码的优化时,我想知道哪些在python中更贵:

if x:
    d = 1
else:
    d = 2
Run Code Online (Sandbox Code Playgroud)

要么

d = 2
if x:
    d = 1
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?我喜欢第二次减少的行数,但想知道重新分配是否比条件切换更昂贵.

python micro-optimization

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

如何测试实现运行速度更快的方法

虽然问题检查输入是否是字符串的类型已经关闭,但两个答案在我的脑海中飙升了一个微优化问题:以下哪两个解决方案会表现更好?

Reed Copsey提供了一个解决方案Char.IsLetter:

string myString = "RandomStringOfLetters";
bool allLetters = myString.All( c => Char.IsLetter(c) );
Run Code Online (Sandbox Code Playgroud)

适合使用正则表达式的解决方案,从马克·拜尔斯:

string s = "RandomStringOfLetters";
bool allLetters = Regex.IsMatch(s, "^[a-z]+$", RegexOptions.IgnoreCase);
Run Code Online (Sandbox Code Playgroud)

不想只问里德或马克的问题我以为我会写一个快速测试来确定哪个表现更好.问题是我没有做过很多代码优化(我倾向于将代码可读性放在首位).

除了在每个运行之前和之后获取时间戳之外,还有哪些其他(更好的?)选项可以确定哪个解决方案运行得更快?

编辑

我修改了Martin的工作答案Console.WriteLine(...)并将其作为控制台应用程序运行.不确定LinqPad究竟是如何运行应用程序的,但结果大致相同:

41
178

c# optimization premature-optimization micro-optimization speed-test

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

代表的表现()

我已经使用$("body").delegate(".selector", "click", function() { ... });了一段时间了,我想知道:如果我将click事件委托给更接近实际元素的包含元素,例如一个table完整的按钮,这会比将同一事件委托给更快body,事件不必泡到目前为止?

基本HTML示例:

<html>
    <body>
        <table>
            <tr>
                <td>
                    <input type="button" value="Delegated element">
                </td>
            </tr>
            <!-- More, identical rows -->
        </table>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

第一个例子,使用body:

$('body').delegate('input[type="button"]', 'click', function() {
    // Do things
});
Run Code Online (Sandbox Code Playgroud)

第二个例子,使用table:

$('table').delegate('input[type="button"]', 'click', function() {
    // Do things
});
Run Code Online (Sandbox Code Playgroud)

上面两个例子中的哪一个更快,如果一个比另一个快,为什么

jquery micro-optimization

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

这可以用switch语句写吗?

我正在编写一个Safari扩展,并希望检测我当前在哪个页面(网址),并做相应的事情.

现在我的代码看起来像:

if (linkHas("facebook.com")) {...}
else if (linkHas("google.com")) {...}
else if (linkHas("yahoo.com")) {...}
Run Code Online (Sandbox Code Playgroud)

where linkHas()是一个函数,如果它有参数,基本上返回1,否则返回0.

是否可以编写这一个单一的switch语句?我已经读过某个地方,如果有超过5个选项,那么switch语句将被实现为哈希表.对于像我这样的小脚本,这里的速度可能并不重要,我只是把它作为一个练习.

javascript micro-optimization

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

x86/x64 asm中的指令重新排序 - 使用最新CPU进行性能优化

在最近的高端Intel CPU上重新排序x64(x86-64)指令可以获得多少性能提升.在非常时间紧迫的情况下值得打扰吗?

我还想知道通过改变寄存器使用/使用额外的寄存器(如果空闲)来获得收益的可能性,以便在某些奇怪的情况下允许更长距离的代码移动?

optimization x86 assembly x86-64 micro-optimization

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

Z80:从堆栈顶部复制到HL

这可以通过以下方式完成:

11 pop hl
10 push hl
Run Code Online (Sandbox Code Playgroud)

在21个周期中。我发现的唯一替代方法是ex (sp),hl,它需要19个周期。缺点是,一旦我用完内容,就必须将其内容交换为原始值,因此在实践中,此方法比第一种方法更昂贵。

还有其他选择吗?

assembly stack z80 micro-optimization

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

编译器在做什么,从而允许通过很少的实际比较就可以完成许多值的比较?

我的问题是,在这种情况下,编译器在做什么,这比我认为的可能更多地优化了代码方式。

鉴于此枚举:

enum MyEnum {
    Entry1,
    Entry2,
    ...   // Entry3..27 are the same, omitted for size.
    Entry28,
    Entry29
};
Run Code Online (Sandbox Code Playgroud)

而这个功能:

bool MyFunction(MyEnum e)
{
    if (
    e == MyEnum::Entry1 || 
    e == MyEnum::Entry3 || 
    e == MyEnum::Entry8 || 
    e == MyEnum::Entry14 || 
    e == MyEnum::Entry15 ||
    e == MyEnum::Entry18 ||
    e == MyEnum::Entry21 || 
    e == MyEnum::Entry22 ||
    e == MyEnum::Entry25)
    {
        return true;
    }
    return false;

}
Run Code Online (Sandbox Code Playgroud)

对于该函数,当使用-Ox优化标志(Godbolt)编译时,MSVC会生成此程序集:

bool MyFunction(MyEnum) PROC                  ; MyFunction
        cmp     ecx, 24
        ja …
Run Code Online (Sandbox Code Playgroud)

c++ optimization assembly x86-64 micro-optimization

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