我正在开发一个ILGenerator
扩展程序,以帮助使用Expression
. 一切都很好,直到我处理整数转换部分。有些东西对我来说确实违反直觉,例如:
conv.i8
转换Int32
到UInt64
conv.u8
转换UInt32
到Int64
它们都是因为评估堆栈不跟踪整数符号。我完全理解原因,只是处理起来有点棘手。
现在我想支持涉及IntPtr
. 它必须更棘手,因为它的长度是可变的。我决定看看 C# 编译器是如何实现它的。
现在专注于特定IntPtr
的Int64
转换。显然,所需的行为应该是:在 64 位系统上无操作,或在 32 位系统上进行符号扩展。
由于在 C# 中native int
由IntPtr
结构包裹,我必须查看其Int64 op_Explicit(IntPtr)
方法的主体。以下是 dnSpy 从 .NET core 3.1.1 反汇编的:
.method public hidebysig specialname static
int64 op_Explicit (
native int 'value'
) cil managed
{
.custom instance void System.Runtime.CompilerServices.IntrinsicAttribute::.ctor() = (
01 00 00 00
)
.custom instance void …
Run Code Online (Sandbox Code Playgroud) 在英特尔内部函数指南,vmulpd
并vfmadd213pd
已延迟5,vaddpd
具有延迟3。
我写了一些测试代码,但所有的结果都慢了 1 个周期。
这是我的测试代码:
.CODE
test_latency PROC
vxorpd ymm0, ymm0, ymm0
vxorpd ymm1, ymm1, ymm1
loop_start:
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
sub rcx, 4
jg loop_start
ret
test_latency ENDP
END
Run Code Online (Sandbox Code Playgroud)
.CODE
test_latency PROC
vxorpd ymm0, ymm0, ymm0
vxorpd ymm1, ymm1, ymm1
loop_start:
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
sub rcx, 4
jg …
Run Code Online (Sandbox Code Playgroud)