我正在学习汇编程序很长一段时间,我正在尝试重写一些简单的过程\函数来查看性能优势(如果有的话).我的主要开发工具是Delphi 2007,第一个例子将使用该语言,但它们也可以很容易地翻译成其他语言.
问题表明:
我们给出了一个无符号字节值,其中八位中的每一位代表一行屏幕中的一个像素.每个单个像素可以是实心(1)或透明(0).换句话说,我们在一个字节值中包含8个像素.我想将这些像素解压缩成一个8字节的数组,就像最年轻的像素(位)将落在数组的最低索引之下一样,依此类推.这是一个例子:
One byte value -----------> eight byte array
10011011 -----------------> [1][1][0][1][1][0][0][1]
Array index number -------> 0 1 2 3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)
下面我介绍解决问题的五种方法.接下来,我将展示他们的时间比较以及我如何衡量这些时间.
我的问题包括两部分:
我问您详细的有关方法的答案DecodePixels4a和DecodePixels4b.为什么方法4b有点慢4a?
例如,如果我的代码没有正确对齐,它会慢一些,那么告诉我给定方法中哪些指令可以更好地对齐,以及如何做到这一点不破坏方法.
我想看看这个理论背后的真实例子.请记住,我正在学习汇编,我想从你的答案中获得知识,这使我将来能够编写更好的优化代码.
你能写更快的常规DecodePixels4a吗?如果是,请提供并描述您已采取的优化步骤.通过更快的例程,我的意思是在测试环境中在最短的时间段内运行的例程,在此处提供的所有例程中.
允许使用所有Intel系列处理器以及与之兼容的处理器.
您将在下面找到我编写的例程:
procedure DecodePixels1(EncPixels: Byte; var DecPixels: TDecodedPixels);
var
i3: Integer;
begin
DecPixels[0] := EncPixels and $01;
for i3 := 1 to 7 do
begin
EncPixels := EncPixels shr 1;
DecPixels[i3] := …Run Code Online (Sandbox Code Playgroud) 在汇编代码中编写Delphi过程或函数时,必须保存哪些寄存器并在过程结束时将其恢复为原始值?
从(内联)汇编代码调用另一个Delphi过程或函数时,我还能期望其他函数与寄存器有什么关系?哪些寄存器将恢复为原始值,哪些可能不会?
(显然,同样的答案适用于这两个问题)
我假设Delphi 的默认调用约定.我知道这EAX用于32位返回值.而看着SysUtils.pas的汇编代码,似乎EBX,ESI并EDI推而恢复,但有些则没有.但是,我找不到任何关于此的文档.
我正在尝试部署CLR TVF(表值函数).在代码中我使用JavaScriptSerializer来解析一些JSON字符串,所以我引用了System.Web.Extensions dll,我的问题从那里开始.
项目构建正常,但当我尝试注册该DLL时,我收到以下错误:
程序集"my_assembly_name"引用程序集"system.web.extensions,version = 4.0.0.0,culture = neutral,publickeytoken = 31bf3856ad364e35.",这在当前数据库中不存在.SQL Server尝试从引用程序集来自的相同位置定位并自动加载引用的程序集,但该操作失败(原因:2(系统找不到指定的文件.)).请将引用的程序集加载到当前数据库中,然后重试您的请求.
我从以下引用了system.web.extensions:
C:\ Program Files(x86)\ Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Web.Extensions.dll
我可以将复制加载设置为true或手动复制程序集,但随后引用错误会更深入 -
程序集"my_assembly_name"引用程序集"system.servicemodel.activation,version = 4.0.0.0,culture = neutral,publickeytoken = 31bf3856ad364e35.",这在当前数据库中不存在.SQL Server尝试从引用程序集来自的相同位置定位并自动加载引用的程序集,但该操作失败(原因:2(系统找不到指定的文件.)).请将引用的程序集加载到当前数据库中,然后重试您的请求.
一切正常,直到我引用Web.Extensions.dll.目标框架是.NET 4.
任何想法/解决方案?
Windows 10上的WSL允许通过bash.exe执行Linux命令和命令行工具.非常有用的是,可以从Windows命令行(cmd.exe)调用Linux工具/命令,方法是将其作为参数传递给bash.exe,如下所示:
bash.exe -c <linux command>
Run Code Online (Sandbox Code Playgroud)
这非常有用,因为它应该允许基于Windows的脚本无缝地组合Windows和Linux工具.
不幸的是,我无法从R脚本调用Linux命令(见下文).
0)系统
安装了Win10 x64 +周年纪念更新+ WSL
1)调用Linux命令的比较情况
以下一切都适合我; 这里显示的只是一个示例调用ls.
从Windows命令行(cmd.exe提示符)
bash -c "ls /mnt/a"
Run Code Online (Sandbox Code Playgroud)
bash -c "ls /mnt/a > /mnt/a/test.txt"
Run Code Online (Sandbox Code Playgroud)同样的工作,如果从...开始 WinKey + R
同样可以在.bat文件中使用.
它可以从编译的代码中调用.我尝试使用Delphi XE2 32位和64位使用ShellExecute:
例如,这些工作(32位和64位):
ShellExecute (0, PChar('open'), PChar('cmd.exe'), PChar('/c c:\windows\system32\bash.exe -c "ls /mnt/a > /mnt/a/test.txt"'), nil, SW_SHOWNORMAL);
Run Code Online (Sandbox Code Playgroud)
或(32位代码):
ShellExecute (0, PChar('open'), PChar('c:\windows\sysnative\bash.exe'), PChar('-c "ls /mnt/a > /mnt/a/test.txt"'), nil, SW_SHOWNORMAL);
Run Code Online (Sandbox Code Playgroud)
或(64位代码):
ShellExecute (0, PChar('open'), PChar('c:\windows\system32\bash.exe'), PChar('-c "ls /mnt/a > /mnt/a/test.txt"'), nil, …Run Code Online (Sandbox Code Playgroud)我想开始玩一些AVX(高级矢量扩展)指令.我知道英特尔提供了一个模拟器来测试包含这些指令的软件(参见这个问题),但由于我不想手动编写十六进制代码,因此出现了哪些汇编器目前知道AVX指令集的问题?
我最感兴趣的是在Windows下运行的汇编程序,可以接受英特尔语法.
我有这个过程交换Word变量的字节(低/高)(它做与System.Swap函数相同的东西).当编译器优化为OFF时,该过程有效,但当它处于ON状态时,该过程无效.任何人都可以帮我吗?
procedure SwapWord(VAR TwoBytes: word);
asm
Mov EBX, TwoBytes
Mov AX, [EBX]
XCHG AL,AH
Mov [EBX], AX
end;
Run Code Online (Sandbox Code Playgroud) 我正在使用Delphi 2010.是否可以告诉Delphi不为函数生成序言?我正在写一些像这样的纯汇编函数:
procedure SomeAssembly; stdcall;
begin
asm
...
end;
end;
Run Code Online (Sandbox Code Playgroud)
我想告诉Delphi不要为这个函数生成一个序言和结语,比如C++的__declspec(naked)特性.
所以没有人浪费他们的时间,我不需要帮助让这些功能与序幕一起工作; 我已经可以做到了.这只是一个很大的不便,将使维护成为一个巨大的麻烦.我将不得不手动检查编译器生成的序言以查看它们的长度,如果更改,我的程序将崩溃.
我也知道我可以将函数编写为字节数组中的一系列字节,但这比查找Delphi序言的长度更糟糕.
如果我这样做
var
a,b,c:cardinal;
begin
a:=$80000000;
b:=$80000000;
c:=a+b;
end;
Run Code Online (Sandbox Code Playgroud)
c将等于0,因为加法溢出.捕获这个溢出的布尔值的最佳方法是什么?(a+b<a) or (a+b<b)?一个非常好的方法是使用内联汇编程序,但我不是那么多的汇编程序(虽然我猜它会包含类似的内容JO)
如何使用Delphi 2007检查盒子是否支持AVX.
我的问题仅限于查询CPU中的支持(假设操作系统正常/带有SP1的Windows 7).
由Chris Lomont 撰写的题为"英特尔®高级矢量扩展简介 "的PDF文档解释了如何执行此操作,并提供了一个示例代码实现,但在c ++中.
它也可以在这个页面上找到.
我试图运行以下,
type
Vector = array [1..4] of Single;
{$CODEALIGN 16}
function add4(const a, b: Vector): Vector; register; assembler;
asm
movaps xmm0, [a]
movaps xmm1, [b]
addps xmm0, xmm1
movaps [@result], xmm0
end;
Run Code Online (Sandbox Code Playgroud)
它提供了对movaps的访问冲突,据我所知,如果内存位置为16对齐,则可以信任movaps.如果movups(不需要对齐),它没有问题.
所以我的问题是,在Delphi XE3中,{$ CODEALIGN}在这种情况下似乎不起作用.
编辑
很奇怪......我尝试了以下几点.
program Project3;
{$APPTYPE CONSOLE}
uses
windows; // if not using windows, no errors at all
type
Vector = array [1..4] of Single;
function add4(const a, b: Vector): Vector;
asm
movaps xmm0, [a]
movaps xmm1, [b]
addps …Run Code Online (Sandbox Code Playgroud) delphi ×8
basm ×7
assembly ×6
avx ×2
x86 ×2
assemblies ×1
c# ×1
clr ×1
delphi-2007 ×1
math ×1
optimization ×1
procedure ×1
r ×1
simd ×1
sql-server ×1
sqlclr ×1
sse ×1
windows ×1