- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试加载 128 位 xmm
注册两个 UInt64
Delphi (XE6) 中的整数。
背景
XMM 寄存器是 128 位的,可以加载多个独立的整数。然后,您可以让 CPU 并行添加这些多个整数。
例如,您可以加载 xmm0 和 xmm1 各有四个 UInt32,然后让 CPU 同时添加所有四对。
xmm0: $00001000 $00000100 $00000010 $00000001
+ + + +
xmm1: $00002000 $00000200 $00000020 $00000002
= = = =
xmm0: $00003000 $00000300 $00000030 $00000003
paddd xmm0, xmm1 //Add packed 32-bit integers (i.e. xmm0 := xmm0 + xmm1)
xmm0: $001F $0013 $000C $0007 $0005 $0003 $0002 $0001
+ + + + + + + +
xmm1: $0032 $001F $0013 $000C $0007 $0005 $0003 $0002
= = = = = = = =
xmm0: $0051 $0032 $001F $0013 $000C $0007 $0005 $0003
paddw xmm0, xmm1 //Add packed 16-bit integers
xmm
注册,你必须使用:
movdqu
)
movdqu
需要一个 128 位的东西来加载 - 它正在加载
双 四字。
TDoubleQuadword = packed record
v1: UInt64; //value 1
v2: UInt64; //value 2
end;
procedure Main;
var
x, y: TDoubleQuadword;
begin
//[1,5] + [2,7] = ?
x.v1 := $0000000000000001;
x.v2 := $0000000000000005;
y.v1 := $0000000000000002;
y.v2 := $0000000000000007;
asm
movdqu xmm0, x //move unaligned double quadwords (xmm0 := x)
movdqu xmm1, y //move unaligned double quadwords (xmm1 := y)
paddq xmm0, xmm1 //add packed quadword integers (xmm0 := xmm0 + xmm1)
movdqu x, xmm0 //move unaligned double quadwords (x := xmm0)
end;
WriteLn(IntToStr(x.v1)+', '+IntToSTr(x.v2));
end;
3, 12
TDoubleQuadword
结构体:
TDoubleQuadword = packed record
v1: UInt64; //value 1
v2: UInt64; //value 2
end;
PDoubleQuadword = ^TDoubleQuadword;
PDoubleQuadword
:
procedure AlignedStuff;
var
x, y: PDoubleQuadword;
begin
x := GetMemory(sizeof(TDoubleQuadword));
x.v1 := $0000000000000001;
x.v2 := $0000000000000005;
y := GetMemory(sizeof(TDoubleQuadword));
y.v1 := $0000000000000002;
y.v2 := $0000000000000007;
asm
movdqu xmm0, x //move unaligned double quadwords (xmm0 := x)
movdqu xmm1, y //move unaligned double quadwords (xmm1 := y)
paddq xmm0, xmm1 //add packed quadword integers (xmm0 := xmm0 + xmm1)
movdqu x, xmm0 //move unaligned double quadwords (v1 := xmm0)
end;
WriteLn(IntToStr(x.v1)+', '+IntToSTr(x.v2));
end;
movdqu xmm0, x //E2107 Operand size mismatch
x
论据
必须为 128 位,编译器知道
x
实际上只是一个(32 位)指针。
//Don't try to pass the 32-bit pointer itself, pass the thing it points to:
movdqu xmm0, x^ //E2107 Operand size mismatch
//Try casting it
movdqu xmm0, TDoubleQuadword(x^) //E2105 Inline assembler error
//i've seen people using square brackets to mean "contents of":
movdqu xmm0, [x] //E2107 Operand size mismatch
movdqu xmm0, Pointer(x)
movdqu xmm0, Addr(x^)
movdqu xmm0, [Addr(x^)]
movdqu xmm0, [Pointer(TDoubleQuadword(x))^]
movdqu xmm0, TDoubleQuadword(x)
x
进入寄存器,而不是 x 中的值。
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TDoubleQuadword = packed record
v1: UInt64; //value 1
v2: UInt64; //value 2
end;
PDoubleQuadword = ^TDoubleQuadword;
TVectorUInt64 = array[0..15] of UInt64;
PVectorUInt64 = ^TVectorUInt64;
procedure AlignedStuff;
var
x, y: PVectorUInt64;
begin
x := GetMemory(sizeof(TVectorUInt64));
//x[0] := ...
//x[1] := ...
// ...
//x[3] := ...
x[4] := $0000000000000001;
x[5] := $0000000000000005;
y := GetMemory(sizeof(TVectorUInt64));
//y[0] := ...
//y[1] := ...
// ...
//y[3] := ...
y[4] := $0000000000000002;
y[5] := $0000000000000007;
asm
movdqu xmm0, TDoubleQuadword(x[4]) //move unaligned double quadwords (xmm0 := x)
movdqu xmm1, TDoubleQuadword(y[4]) //move unaligned double quadwords (xmm1 := y)
paddq xmm0, xmm1 //add packed quadword integers (xmm0 := xmm0 + xmm1)
movdqu TDoubleQuadword(x[4]), xmm0 //move unaligned double quadwords (v1 := xmm0)
end;
WriteLn(IntToStr(x[4])+', '+IntToSTr(x[5]));
end;
begin
try
AlignedStuff;
Writeln('Press enter to close...');
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
TVectorUInt64 = array[0..15] of UInt64;
PVectorUInt64 = ^TVectorUInt64;
var
v: PVectorUInt64;
begin
v := GetMemoryAligned(sizeof(TVectorUInt64), 64); //64-byte alignment
//v is initalized
for i := 0 to 15 do
begin
v[0] := v[0] + v[4];
v[1] := v[1] + v[5];
v[2] := v[2] + v[6];
v[3] := v[3] + v[7];
//..and some more changes to v0..v3
//..and some more changes to v12..v15
v[8] := v[8] + v[12];
v[9] := v[9] + v[13];
v[10] := v[10] + v[14];
v[11] := v[11] + v[15];
//...and some more changes to v4..v7
v[0] := v[0] + v[4];
v[1] := v[1] + v[5];
v[2] := v[2] + v[6];
v[3] := v[3] + v[7];
//...and some more changes to v0..v3
//...and some more changes to v12..v15
v[8] := v[8] + v[12];
v[9] := v[9] + v[13];
v[10] := v[10] + v[14];
v[11] := v[11] + v[15];
//...and some more changes to v4..v7
v[0] := v[0] + v[4];
v[1] := v[1] + v[5];
v[2] := v[2] + v[6];
v[3] := v[3] + v[7];
//..and some more changes to v0..v3
//..and some more changes to v12..v15
v[8] := v[8] + v[12];
v[9] := v[9] + v[13];
v[10] := v[10] + v[14];
v[11] := v[11] + v[15];
//...and some more changes to v4..v7
v[0] := v[0] + v[4];
v[1] := v[1] + v[5];
v[2] := v[2] + v[6];
v[3] := v[3] + v[7];
//...and some more changes to v0..v3
//...and some more changes to v12..v15
v[8] := v[8] + v[12];
v[9] := v[9] + v[13];
v[10] := v[10] + v[14];
v[11] := v[11] + v[15];
//...and some more changes to v4..v7
end;
//v[0] := v[0] + v[4];
//v[1] := v[1] + v[5];
asm
movdqu xmm0, v[0]
movdqu xmm1, v[4]
paddq xmm0, xmm1
movdqu v[0], xmm0
end
//v[2] := v[2] + v[6];
//v[3] := v[3] + v[7];
asm
movdqu xmm0, v[2]
movdqu xmm1, v[6]
paddq xmm0, xmm1
movdqu v[2], xmm0
end
//v[8] := v[8] + v[12];
//v[9] := v[9] + v[13];
asm
movdqu xmm0, v[8]
movdqu xmm1, v[12]
paddq xmm0, xmm1
movdqu v[8], xmm0
end
//v[10] := v[10] + v[14];
//v[11] := v[11] + v[15];
asm
movdqu xmm0, v[10]
movdqu xmm1, v[14]
paddq xmm0, xmm1
movdqu v[10], xmm0
end
[contentsOfSquareBrackets]
会工作movdqu xmm0, TPackedQuadword
movdqu xmm0, PPackedQuadword^
*"The compiler does not support dereferencing a pointer inside an
asm
block. No matter if you try that with a caret (^
), or square brackets ([...]
). It just cannot be done.
asm
中的指针阻止,然后发布答案。
最佳答案
Delphi 中的内联汇编程序的文档没有应有的全面,而且很多功能根本没有记录。所以我不能确定这一点,但据我所知,根本不支持您尝试编写的汇编语句,其中一个操作数是指针类型的局部变量。
我强烈建议您避免在同一个函数中混用 Pascal 代码和汇编代码。当你在同一个函数中的 Pascal 代码和汇编代码之间移动时,它很难生成高效的代码,并且很难管理寄存器的使用。
我个人规定永远不要混合使用 Pascal 和内联汇编程序。始终编写纯汇编函数。例如,对于 32 位代码,您将编写一个完整的程序,如下所示:
{$APPTYPE CONSOLE}
type
PDoubleQuadword = ^TDoubleQuadword;
TDoubleQuadword = record
v1: UInt64;
v2: UInt64;
end;
function AddDoubleQuadword(const dqw1, dqw2: TDoubleQuadword): TDoubleQuadword;
asm
movdqu xmm0, [eax]
movdqu xmm1, [edx]
paddq xmm0, xmm1
movdqu [ecx], xmm0
end;
procedure AlignedStuff;
var
x, y: PDoubleQuadword;
begin
New(x);
x.v1 := $0000000000000001;
x.v2 := $0000000000000005;
New(y);
y.v1 := $0000000000000002;
y.v2 := $0000000000000007;
x^ := AddDoubleQuadword(x^, y^);
Writeln(x.v1, ', ', x.v2);
end;
begin
AlignedStuff;
Readln;
end.
3, 12
Or you could use a record with operators:
type
PDoubleQuadword = ^TDoubleQuadword;
TDoubleQuadword = record
v1: UInt64;
v2: UInt64;
class operator Add(const dqw1, dqw2: TDoubleQuadword): TDoubleQuadword;
end;
class operator TDoubleQuadword.Add(const dqw1, dqw2: TDoubleQuadword): TDoubleQuadword;
asm
movdqu xmm0, [eax]
movdqu xmm1, [edx]
paddq xmm0, xmm1
movdqu [ecx], xmm0
end;
x^ := x^ + y^;
关于delphi - 使用指向数组中的两个 UInt64 加载 xmm 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53501137/
我有以下代码 unsigned int headerbytes = 0U; headerbytes = (unsigned int*)strtoull(packet_space->header
我有这段无法编译的代码: public struct MyStruct { private fixed uint myUints[32]; public uint[] MyUints
在 Go 中,从函数返回哪个更有效:返回 uint 还是返回 *uint? 该函数在 cpu 密集型库的内部 for 循环中调用。 最佳答案 一般来说,只要效率是个问题,您就应该运行基准测试。 让我们
int 加上 unsigned int 返回一个 unsigned int。应该这样吗? 考虑这段代码: #include #include #include class test {
我正在尝试从可通过 URL 访问的内容中初始化一个字符串: actualresponse.response = String(contentsOfURL: url, usedEncoding: NSU
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 1年前关闭。 Improve this
我从函数 Swift 得到类型为 UnsafeMutablePointer 的结果 我可以把它转换到UInt吗? ? 最佳答案 只需使用memory 属性来访问底层数据。 let ptr: Unsaf
我深入了解了 List并发现了以下代码: public T this[int index] { get { // Following trick can red
我在 this page on bit twiddling 的帮助下编写了这个函数: uint16_t *decode(uint64_t instr) { // decode instr (thi
我正在从微 Controller 读取两个寄存器。一个具有 4 位 MSB(前 4 位有一些其他内容),另一个具有 8 位 LSB。我想将其转换为一个 12 位 uint(准确地说是 16 位)。到目
要演示的示例代码: public int FindComplement(int num) { //uint mask = ~0; //<-- error CS0031 //
$ rustc --test mapAsMapKey.rs mapAsMapKey.rs:18:43: 18:52 error: mismatched types: expected `fn@(&&@
一般问题:我有一个很大的二维点空间,里面稀疏地分布着点。把它想象成一 block 撒满黑点的白色大 Canvas 。我必须多次迭代和搜索这些点。 Canvas (点空间)可能很大,接近极限int 的值
假设我们只是调用一个普通数字,数字会启动什么。 uint256 plainNumber 我明白它是零。但是我要问的是,有没有办法检测该数字是由编译器还是用户变量设置的。例如... uint256 pl
我试图在 leetcode.com ( https://leetcode.com/problems/number-of-1-bits/ ) 上解决一个简单的问题,我遇到了一个奇怪的行为,这可能是我缺乏
uint number = 0x418 in bits : 0000010000011000 uint number1 = 0x8041 in bits: 1000000001000001 uint
我如何在 C# 中生成具有某个最大值的伪随机 uint? (不需要最低限度。)似乎有很多问题要求完全随机,但没有上限。 澄清:此上限可能大于 int.MaxValue,因此仅强制转换 Random.N
我已经用私有(private)数据成员围绕 ulong 编写了一个简单的包装器。我希望能够将包装器转换为 ulong 以检索数据。我希望强制转换为 uint 并丢失数据是非法的,因此我没有编写对 ui
哪些是“Uint”变量?就是有“Uint8”、“Uint16”等…… 但是它们是什么? 现在我有一些时间使用 C++,但我从来不需要使用这些变量并引起我的好奇。 提前致谢。 最佳答案 uint 不是标
我有一个 native 方法,它需要一个指针来写出一个双字(uint)。 现在我需要从 (Int) 指针中获取实际的 uint 值,但是 Marshal 类只有方便的方法来读取(有符号)整数。 如何从
我是一名优秀的程序员,十分优秀!