相关疑难解决方法(0)

在运行中生成矢量常数的最佳指令序列是什么?

"最佳"意味着最少的指令(或最少的uops,如果任何指令解码到多个uop).机器码大小(以字节为单位)是相同insn计数的平局.

恒定生成本质上是一个新的依赖链的开始,所以延迟很重要.在循环内生成常量也很不寻常,因此吞吐量和执行端口需求也几乎无关紧要.

生成常量而不是加载它们需要更多指令(除了全零或全一),因此它会占用宝贵的uop-cache空间.这可能是比数据缓存更有限的资源.

Agner Fog优秀的优化装配指南涵盖了这一点Section 13.4.表13.10具有用于产生向量序列,每一个元素是0,1,2,3,4,-1,或-2,与从8位到64位单元大小.表13.11具有用于产生一些浮点值序列(0.0,0.5,1.0,1.5,2.0,-2.0,和位掩码为符号位.)

Agner Fog的序列仅使用SSE2,无论是设计还是因为它尚未更新一段时间.

使用短的非显而易见的指令序列可以生成哪些其他常量? (具有不同移位计数的进一步扩展是显而易见的而不是"有趣的".)是否有更好的序列用于生成Agner Fog列出的常量?

如何将128位immediates移动到XMM寄存器说明了将任意128b常量放入指令流的一些方法,但这通常是不合理的(它不会节省任何空间,并占用大量的uop-cache空间.)

x86 assembly sse simd avx

24
推荐指数
1
解决办法
1733
查看次数

将CPU寄存器中的所有位有效地设置为1

要清除所有位,您经常会看到一个独占或在XOR eax, eax.反过来也有这样的伎俩吗?

我能想到的是用额外的指令反转零.

assembly arm x86-64 mips

17
推荐指数
1
解决办法
2154
查看次数

函数调用循环比空循环快

我将一些程序集与一些c链接起来测试函数调用的成本,使用以下程序集和c源代码(分别使用fasm和gcc)

部件:

format ELF

public no_call as "_no_call"
public normal_call as "_normal_call"

section '.text' executable

iter equ 100000000

no_call:
    mov ecx, iter
@@:
    push ecx
    pop ecx
    dec ecx
    cmp ecx, 0
    jne @b
    ret

normal_function:
    ret

normal_call:
    mov ecx, iter
@@:
    push ecx
    call normal_function
    pop ecx
    dec ecx
    cmp ecx, 0
    jne @b
    ret
Run Code Online (Sandbox Code Playgroud)

c来源:

#include <stdio.h>
#include <time.h>

extern int no_call();
extern int normal_call();

int main()
{
    clock_t ct1, ct2;

    ct1 = clock();
    no_call();
    ct2 = clock(); …
Run Code Online (Sandbox Code Playgroud)

c performance x86 assembly fasm

15
推荐指数
1
解决办法
969
查看次数

我可以将64位常数添加到64位寄存器吗?

在我的64位Intel机器下面代码工作:

mov rdi, 1 << 40
add r10, rdi
Run Code Online (Sandbox Code Playgroud)

而这相当于一个产生警告并且不起作用:

add r10, 1 << 40
Run Code Online (Sandbox Code Playgroud)

我应该坚持1号还是我错过了什么?这种行为似乎很尴尬.

代码nr 2产生的警告:

warning: signed dword immediate exceeds bounds
Run Code Online (Sandbox Code Playgroud)

assembly x86-64

5
推荐指数
1
解决办法
1045
查看次数

如何在NASM中推送64位int?

我正在尝试推送一个64位整数但是在组装NASM时似乎想把它看成是一个DWORD而不是QWORD.

我正在使用ASM来创建shellcode,我需要将64位DLL注入到64位进程中.第一个QWORD是旧指令指针,第二个是包含DLL地址的地址,第三个是LoadLibrary的地址.占位符在运行时填充.

section .text
global _start   

_start:
BITS 64
PUSH QWORD 0xACEACEACACEACEAC
PUSHFQ
push rax
PUSH QWORD 0xACEACEACACEACEAC
MOV RAX, 0xACEACEACACEACEAC
CALL RAX
pop RAX
POPFQ
RETN
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 nasm

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

BITWISE AND操作如何在C程序中占用比ARITHMETIC ADDITION操作更多的CPU时钟?

我想测试按位运算是否真的比算术运算更快.我以为他们是.

我写了一个小的C程序来测试这个假设,令我惊讶的是,加法平均比按位AND运算少.这对我来说是令人惊讶的,我无法理解为什么会这样.

根据我所知的附加,来自较低有效位的进位应该被携带到下一位,因为结果也取决于进位.对我来说逻辑运算符比加法更慢是没有意义的.

我的鳕鱼在下面:

#include<stdio.h>
#include<time.h>

int main() 
{
   int x=10;
   int y=25;
   int z=x+y;
   printf("Sum of x+y = %i", z);
   time_t start = clock();
   for(int i=0;i<100000;i++)z=x+y;
   time_t stop = clock();

   printf("\n\nArithmetic instructions take: %d",stop-start);
   start = clock();
   for(int i=0;i<100000;i++)z=x&y;
   stop = clock();

   printf("\n\nLogic instructions take: %d",stop-start);
}
Run Code Online (Sandbox Code Playgroud)

一些结果:

Arithmetic instructions take: 327
Logic instructions take: 360

Arithmetic instructions take: 271
Logic instructions take: 271

Arithmetic instructions take: 287
Logic instructions take: 294

Arithmetic instructions take: 279
Logic instructions take: …
Run Code Online (Sandbox Code Playgroud)

c assembly instructions logical-operators integer-arithmetic

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