目录
创建一个新的AArch64项目
编译本机WoA应用程序
针对x86仿真对AArch64进行基准测试
下一步
Windows on Arm(WoA)设备,例如Surface Pro X,可以在仿真中运行x86 Windows应用程序。借助内部版本,WoA设备还可以模拟x64 Windows应用程序。
仿真将x86 CPU指令转换为Arm指令。当然,这不如原生运行应用程序快——即直接针对Arm架构和指令集编译。因此,如果您想利用平台的强大功能并最大限度地延长电池寿命,您应该创建本机应用程序。
您可以使用多种方法为WoA创建本机应用程序。例如,您可以创建一个面向Arm设备的通用Windows平台(UWP)应用程序。从.NET Framework 5.0.8版本开始,Windows Forms、Windows Presentation Foundation(WPF)和UWP都具有原生的Arm支持。如果您将这些框架中的任何一个用于现有应用程序,那么为WoA设备本地编译它很简单。
在本文中,我们将采用在x86-64机器上开发的Windows窗体(WinForms)应用程序并将其移植到本机WoA WinForms应用程序。要继续学习,您应该熟悉C#、.NET和WinForms。
创建一个新的AArch64项目作为演示,让我们首先创建一个新的Windows窗体项目,然后将其编译为AArch64(64位Arm)。首先,确保您安装了带有.NET桌面开发组件的Visual Studio 2019 。在Visual Studio安装程序中看起来像这样:
接下来,我们打开Visual Studio并选择Create a new project。在模板列表中,我们选择Windows Forms App, 而不是Windows Forms App(.NET Framework)。我们不想要Windows窗体应用程序,因为它适用于.NET Framework 4.x,而我们想要.NET 5。
然后,我们单击下一步并为我们的应用程序选择项目名称和位置。
然后向导会询问我们要定位哪个框架:.NET Core 3.1或.NET 5。虽然我们在定位.NET Core 3.1时可以编译为AArch64,但定位到.NET 5时性能更好,因为它更多地使用硬件内在函数。因此,我们选择.NET 5.0并单击Create。然后我们可以像往常一样开始开发Windows窗体应用程序。
作为一个简单的演示,让我们创建一个只有一个按钮的表单。当用户单击它时,会弹出一个消息框,显示流程架构。
我们首先在设计器中给表单添加一个按钮:
然后,我们双击按钮添加一个Click事件处理程序。我们使用以下代码作为事件处理程序:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString());
}
如果您在开发机器上运行应用程序并按下按钮,它可能会显示x64(当然,除非您不在x64设备上)。
编译本机WoA应用程序现在,让我们为WoA设备本地编译我们的应用程序。首先,我们在解决方案资源管理器中双击“属性”:
这样做会打开项目的属性。
然后我们转到“构建”选项卡。
然后,我们所要做的就是将平台目标更改为ARM64并重新编译。我们现在无法在我们的开发机器上运行应用程序,因为架构不兼容,所以让我们尝试在Arm设备上运行它。我们将bin/Debug/net5.0-windows目录复制到我们的Arm设备并尝试在该目录中运行WinFormsArm.exe。
如果您尚未安装.NET运行时,设备会提示您先安装并将您重定向到下载页面。在该页面上,选择“运行控制台应用程序”下的“下载Arm64 ”,运行安装程序,然后对“运行桌面应用程序”执行相同操作(两者都需要)。
当.NET运行时完成安装时,我们尝试运行应用程序并再次按下按钮。它现在在消息框中显示Arm64。
为了进行比较,您还可以尝试将Platform目标设置为x86,在您的Arm设备上下载x86运行时,然后运行x86可执行文件。您将看到消息框显示“x86”,因此它正在仿真下运行。
如您所见,为AArch64编译Windows窗体应用程序非常简单:您只需确保面向.NET 5并将平台目标更改为ARM64。对于.NET Framework 4.x上的现有应用程序,您应该在Visual Studio中创建一个新项目(因为.NET 5和.NET Framework 4.x的项目类型不同)并从旧项目导入文件。
在为Windows on Arm创建或移植应用程序时,请记住缩放和布局Windows设置。Surface Pro等设备在相对较小的屏幕上具有高分辨率,因此建议设置为200%。另一方面,您的开发机器可能已将此值设置在100%到150%之间。
在规模和布局设置影响,例如,文本和表单大小。但是像PictureBox这样的控件不能缩放。无论此设置的值如何,您都需要确保您的应用程序看起来不错。否则,您的表单在Arm设备上可能看起来非常扭曲。当然,这种担忧不是Arm独有的,因为所有Windows设备都有该设置,但最好记住。
针对x86仿真对AArch64进行基准测试为AArch64本地编译而不是模拟x86二进制文件的优势在于它更快。让我们做一个快速的基准测试来确认这是真的。
我们的基准测试包括生成一个400 x 400的位图,用随机像素填充它,并显示结果。我们期望在为AArch64编译时比为x86编译更快。
我们将使用一个新按钮来扩展我们的表单来启动基准测试,一个标签来显示花费了多长时间,以及一个PictureBox显示图像。
首先,我们命名按钮 benchmarkBtn、标签 benchmarkLabel和PictureBox benchmarkPbox。然后,我们双击benchmarkBtn添加一个执行基准测试的点击事件处理程序:
private void benchmarkBtn_Click(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Random rng = new Random();
Bitmap bmp = new Bitmap(400, 400);
for (int i = 0; i < 10; i++)
{
for (int x = 0; x < 400; x++)
{
for (int y = 0; y < 400; y++)
{
bmp.SetPixel(x, y, Color.FromArgb(rng.Next()));
}
}
}
benchmarkPbox.Image = bmp;
sw.Stop();
benchmarkLabel.Text = "Benchmark time: " + sw.Elapsed.ToString();
}
我们需要在文件顶部添加using System.Diagnostics;,因为我们的代码使用了Stopwatch。
基准测试使用SetPixel一次填充一个像素,这是生成随机图像的一种低效方式。然而,这种基准并不重要,因为结果只是相互比较才有意义。
生成随机图像的整个过程重复十次以平均每次迭代的结果。只显示最后一个图像,但这也无关紧要。当图片生成完成后,我们的应用程序会在标签上显示经过的时间。
尝试为AArch64和x86编译应用程序,然后在您的Arm设备上运行它们。您还需要将构建配置设置为Release而不是Debug以优化代码。然后可执行文件最终在bin/Release而不是bin/Debug。
在我的Arm设备上,原生AArch64应用程序在0.6到0.7秒之间完成了基准测试。模拟的x86应用程序需要1.2到1.5秒。因此,本机应用程序以两倍的速度执行此基准测试。当然,它是针对特定情况的,并非所有操作都具有相同的相对速度,但它确实强调了本机编译的应用程序效率更高,正如我们预期的那样。
下一步要充分利用WoA平台,您应该针对Arm架构本地创建应用程序。使用Windows窗体应用程序,可以轻松定位.NET 5并告诉Visual Studio为AArch64进行编译。
要了解有关此主题的更多信息,您可能希望探索在Visual Studio中远程调试C#或Visual Basic项目。现在您知道如何为WoA编写原生Windows窗体应用程序,开始构建您自己的Arm原生WinForms应用程序!
https://www.codeproject.com/Articles/5311216/Building-a-Native-Windows-on-Arm-App-with-WinForms