zyl910

优化技巧、硬件体系、图像处理、图形学、游戏编程、国际化与文本信息处理。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

作者:


在前一篇文章(在亚马逊AWS上创建ARM服务器并配置好RDP远程桌面连接的心得)里,我们成功在亚马逊AWS上创建了Ubuntu系统的ARM服务器。现在准备在该服务器上安装 .NET SDK。

一、尝试 apt-get 安装

首先尝试了之前在 x86 处理器的Ubuntu系统上安装 .NET SDK的经验,使用 apt-get 来安装。

ubuntu@ip-175-76-22-54:~$ sudo apt-get install -y dotnet6
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package dotnet6

遇到错误,找不到“dotnet6”的安装包。随后换了几个版本也不行,sudo apt-get update 也没效果。

于是查找了一下官方文档,发现 《在 Ubuntu 上安装 .NET SDK 或 .NET 运行时》中有这一段话:

仅在 x64 体系结构上支持包管理器安装。 对于 Arm 等其他体系结构,必须通过其他一些方式安装 .NET,例如,通过 Snap 和安装程序脚本进行安装,或通过手动提取二进制文件进行安装。

原来ARM体系不支持包管理安装,看来得换一种办法来安装了。

二、尝试 snap 安装

现在来尝试 snap 安装。
摘录官方文档:

若要安装适用于 .NET SDK 的 Snap 包,请运行 snap install 命令。 使用 --channel 参数来指明要安装哪个版本。 如果省略此参数,则使用 latest/stable。 在下面的示例中,指定的是 7.0:

Bash
sudo snap install dotnet-sdk --classic --channel=7.0

随后参考它,在我们的ARM服务器上执行命令。

ubuntu@ip-175-76-22-54:~$ sudo snap install dotnet-sdk --classic --channel=7.0
error: snap "dotnet-sdk" is not available on 7.0/stable but other tracks exist.

       Please be mindful that different tracks may include different features.
       Get more information with 'snap info dotnet-sdk'.

有报错,说找不到可用的安装包。
于是用命令查询了一下 snap 上有哪些 dotnet-sdk 版本。

ubuntu@ip-175-76-22-54:~$ snap info dotnet-sdk
name:      dotnet-sdk
summary:   Develop high performance applications in less time, on any platform.
publisher: Microsoft .NET Core (dotnetcore✓)
store-url: https://snapcraft.io/dotnet-sdk
contact:   https://dot.net/core
license:   MIT
description: |
  .NET Core is the modular and high performance implementation of .NET for
  creating web applications and services that run on Windows, Linux and Mac.
  It is open source and it can share the same code with .NET Framework and
  Xamarin apps.

  .NET Core is a .NET Foundation project. https://dotnetfoundation.org/
snap-id: uHc4y9lWxyqYfxsqcr4xILzAai4L1BHs
channels:
  5.0/stable:    –
  5.0/candidate: –
  5.0/beta:      –
  5.0/edge:      5.0.100-preview.3.20216.6 2020-04-21 (79) 127MB classic

发现它不支持 .net 7.0,仅有 .net 5.0版的。且没有稳定版(stable),只在edge通道有一个预览版(preview)。
故再换一种办法吧。

三、使用 dotnet-install 脚本安装

3.1 脚本准备

摘自官方文档:

脚本安装
dotnet-install 脚本用于 SDK 和运行时的自动化和非管理员安装。 可通过 https://dot.net/v1/dotnet-install.sh 下载脚本。

重要:需要 Bash 才能运行该脚本。
运行此脚本之前,需要授予此脚本作为可执行文件运行的权限:

Bash
sudo chmod +x ./dotnet-install.sh

上文介绍了脚本的网址,于是我们可以用 wget 命令下载该脚本,然后参考它修改文件属性。

ubuntu@ip-175-76-22-54:~$ wget https://dot.net/v1/dotnet-install.sh
--2022-11-26 08:28:01--  https://dot.net/v1/dotnet-install.sh
Resolving dot.net (dot.net)... 20.53.203.50, 20.112.52.29, 20.103.85.33, ...
Connecting to dot.net (dot.net)|20.53.203.50|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh [following]
--2022-11-26 08:28:02--  https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh
Resolving dotnet.microsoft.com (dotnet.microsoft.com)... 13.107.246.46, 13.107.213.46, 2620:1ec:46::46, ...
Connecting to dotnet.microsoft.com (dotnet.microsoft.com)|13.107.246.46|:443... connected.
HTTP request sent, awaiting response... 200 OK
Cookie coming from dotnet.microsoft.com attempted to set domain to dotnetwebsite.azurewebsites.net
Cookie coming from dotnet.microsoft.com attempted to set domain to dotnetwebsite.azurewebsites.net
Length: 58293 (57K) [application/x-sh]
Saving to: ‘dotnet-install.sh’

dotnet-install.sh   100%[===================>]  56.93K  --.-KB/s    in 0.003s

2022-11-26 08:28:02 (20.4 MB/s) - ‘dotnet-install.sh’ saved [58293/58293]

ubuntu@ip-175-76-22-54:~$ sudo chmod +x ./dotnet-install.sh

3.2 安装最新长期支持 (LTS)版 .NET 6.0

对于安装最新的长期支持 (LTS),可参考官方文档:

该脚本默认安装最新的 长期支持 (LTS) SDK 版本,即 .NET 6。 若要安装最新版本(可能不是 LTS) 版本的 (版本),请使用 --version latest 参数。

Bash
./dotnet-install.sh --version latest

注意它在运行脚本时,没有加“sudo”,表示该脚本支持将程序安装到当前用户的目录下,无需管理员权限。
但这对多用户使用时会带来麻烦。为了避免每个用户都装一次,于是也可选择用“sudo”来安装,这样便会安装在所有用户都能访问的路径中。

ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh
dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:
dotnet-install: - The SDK needs to be installed without user interaction and without admin rights.
dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs.
dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.

dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.403/dotnet-sdk-6.0.403-linux-arm64.tar.gz
dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.403/dotnet-sdk-6.0.403-linux-arm64.tar.gz
dotnet-install: Installed version is 6.0.403
dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script.
dotnet-install: Note that the script does not resolve dependencies during installation.
dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section.
dotnet-install: Installation finished successfully.

从上面的信息可看出,已安装好 .NET SDK 6.0,它装在 /root/.dotnet 目录中。

3.3 安装最新版本 .NET 7.0

对于安装指定的版本,可参考官方文档:

可以使用 参数安装特定的主版本 --channel ,以指示特定版本。 以下命令安装 .NET 7.0 SDK。

Bash
./dotnet-install.sh --channel 7.0

按照文档,进行安装。

ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh --channel 7.0
dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:
dotnet-install: - The SDK needs to be installed without user interaction and without admin rights.
dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs.
dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.

dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/7.0.100/dotnet-sdk-7.0.100-linux-arm64.tar.gz
dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/7.0.100/dotnet-sdk-7.0.100-linux-arm64.tar.gz
dotnet-install: Installed version is 7.0.100
dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script.
dotnet-install: Note that the script does not resolve dependencies during installation.
dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section.
dotnet-install: Installation finished successfully.

.NET SDK 7.0 安装成功。

3.4 安装旧版本 .NET Core 3.1

官方文档的“受支持”列表里还有“.NET Core 3.1”,于是也可安装。

ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh --channel 3.1
dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:
dotnet-install: - The SDK needs to be installed without user interaction and without admin rights.
dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs.
dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.

dotnet-install: Attempting to download using primary link https://dotnetcli.azureedge.net/dotnet/Sdk/3.1.425/dotnet-sdk-3.1.425-linux-arm64.tar.gz
dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/3.1.425/dotnet-sdk-3.1.425-linux-arm64.tar.gz
dotnet-install: Installed version is 3.1.425
dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script.
dotnet-install: Note that the script does not resolve dependencies during installation.
dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section.
dotnet-install: Installation finished successfully.

.NET Core SDK 3.1 安装成功。

3.5 安装不受支持的版本 .NET 5.0

官方文档中,“.NET 5.0”在“不受支持”列表里,它会否能安装呢?于是我尝试了一下。

ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh --channel 5.0
dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:
dotnet-install: - The SDK needs to be installed without user interaction and without admin rights.
dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs.
dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.

dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.408/dotnet-sdk-5.0.408-linux-arm64.tar.gz
dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.408/dotnet-sdk-5.0.408-linux-arm64.tar.gz
dotnet-install: Installed version is 5.0.408
dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script.
dotnet-install: Note that the script does not resolve dependencies during installation.
dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section.
dotnet-install: Installation finished successfully.

.NET SDK 5.0 安装成功。
看来“不受支持”仅是指没有技术支持,还是可以用 dotnet-install 脚本安装该版本的。

3.6 查看.NET SDK信息

装好了,想查看一下安装的SDK信息,于是执行了以下命令。

ubuntu@ip-175-76-22-54:~$ dotnet --list-sdks
dotnet: command not found

报错了,找不到命令。
原来是它没被自动加到环境变量,故需要写全路径。

ubuntu@ip-175-76-22-54:~$ /root/.dotnet/dotnet --list-sdks
-bash: /root/.dotnet/dotnet: Permission denied

这次遇到了“Permission denied”报错。
看来是跟先前的“sudo”安装有关,需要使用“sudo”才能执行它。

ubuntu@ip-175-76-22-54:~$ sudo /root/.dotnet/dotnet --list-sdks
3.1.425 [/root/.dotnet/sdk]
5.0.408 [/root/.dotnet/sdk]
6.0.403 [/root/.dotnet/sdk]
7.0.100 [/root/.dotnet/sdk]

ubuntu@ip-175-76-22-54:~$ sudo /root/.dotnet/dotnet --info
.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  22.04
 OS Platform: Linux
 RID:         ubuntu.22.04-arm64
 Base Path:   /root/.dotnet/sdk/7.0.100/

Host:
  Version:      7.0.0
  Architecture: arm64
  Commit:       d099f075e4

.NET SDKs installed:
  3.1.425 [/root/.dotnet/sdk]
  5.0.408 [/root/.dotnet/sdk]
  6.0.403 [/root/.dotnet/sdk]
  7.0.100 [/root/.dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.31 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.11 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.0 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.31 [/root/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [/root/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.11 [/root/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.0 [/root/.dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

成功得到了安装信息。

四、运行 .NET 程序

在Windows系统中,可方便的双击运行 .NET 程序;或是在命令行里直接输入程序的exe文件名,来运行程序。
而在非Windows系统中,需要通过 dotnet 命令来运行 .NET 程序。且命令行参数里不是传递主程序的exe文件名,而应该传递主程序的dll文件名。
详见官方文档,摘录:

运行应用程序:

.NET CLI
dotnet [--additionalprobingpath <PATH>] [--additional-deps <PATH>]
    [--fx-version <VERSION>]  [--roll-forward <SETTING>]
    <PATH_TO_APPLICATION> [arguments]

dotnet exec [--additionalprobingpath] [--additional-deps <PATH>]
    [--depsfile <PATH>]
    [--fx-version <VERSION>]  [--roll-forward <SETTING>]
    [--runtimeconfig <PATH>]
    <PATH_TO_APPLICATION> [arguments]

4.1 运行 .NET 7.0 程序

可以在其他电脑上开发程序,然后将编译后的文件,拷贝到ARM服务器上再运行。平台(Platform)选 AnyCPU 就行,无需特意选 ARM64。且不用发布(Publish),直接将“bin”文件夹下的 Debug或Release目录 拷贝过去就行。
于是我将前段时间开发的 VectorClassDemo 程序拷贝了过去,顺便能检查一下 .NET 对ARM的内在函数的支持性。将该程序分别用 .NET 5.0/7.0编译一下,然后拷贝过去。

若想将文件拷贝到远程的服务器上,可以用 scp 等命令。或者可以用RDP远程桌面连接过去,在本机复制文件,然后在远程桌面的文件管理器中粘贴,便能将文件复制过去。
文件复制成功后,进入程序所在目录,然后便可以用 dotnet 命令来执行程序了。例如我的这个程序的主程序的dll文件名为“VectorClassDemo50.dll”,于是语句为“sudo /root/.dotnet/dotnet ./VectorClassDemo50.dll”。
20221126164739_run_dotnet.png

输出信息摘录如下:

ubuntu@ip-175-76-22-54:~/Documents/VectorClassDemo50/net7.0$ sudo /root/.dotnet/dotnet ./VectorClassDemo50.dll
VectorClassDemo50

IsRelease:	True
EnvironmentVariable(PROCESSOR_IDENTIFIER):	
Environment.ProcessorCount:	2
Environment.Is64BitOperatingSystem:	True
Environment.Is64BitProcess:	True
Environment.OSVersion:	Unix 5.15.0.1023
Environment.Version:	7.0.0
RuntimeEnvironment.GetRuntimeDirectory:	/root/.dotnet/shared/Microsoft.NETCore.App/7.0.0/
RuntimeInformation.FrameworkDescription:	.NET 7.0.0
BitConverter.IsLittleEndian:	True
IntPtr.Size:	8
Vector.IsHardwareAccelerated:	True
Vector<byte>.Count:	16	# 128bit
Vector<T>.Assembly.CodeBase:	file:///root/.dotnet/shared/Microsoft.NETCore.App/7.0.0/System.Private.CoreLib.dll

[Intrinsics.Arm]
AdvSimd.IsSupported:	True
AdvSimd.Arm64.IsSupported:	True
Aes.IsSupported:	True
Aes.Arm64.IsSupported:	True
ArmBase.IsSupported:	True
ArmBase.Arm64.IsSupported:	True
Crc32.IsSupported:	True
Crc32.Arm64.IsSupported:	True
Dp.IsSupported:	True
Dp.Arm64.IsSupported:	True
Rdm.IsSupported:	True
Rdm.Arm64.IsSupported:	True
Sha1.IsSupported:	True
Sha1.Arm64.IsSupported:	True
Sha256.IsSupported:	True
Sha256.Arm64.IsSupported:	True

-- Single, Vector<Single>.Count=4 --
srcT:	<-3.4028235E+38, Infinity, NaN, -1.2>	# (FF7FFFFF 7F800000 FFC00000 BF99999A)
srcAllOnes:	<NaN, NaN, NaN, NaN>	# (FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF)
Abs(srcT):	<3.4028235E+38, Infinity, NaN, 1.2>	# (7F7FFFFF 7F800000 7FC00000 3F99999A)

可以看到:

  • 该程序正确的以“64位 .NET 7.0 程序”的方式在运行。
  • 向量类型支持硬件加速(Vector.IsHardwareAccelerated),且向量类型的长度为 128bit。这是因为ARM的 AdvSimd 指令集的数据长度最长为128位。
  • 目前的所有ARM内在函数(Intrinsics.Arm)的IsSupported都是true,表示都支持。

4.2 运行 .NET 5.0 程序

随后又尝试运行了 .NET 5.0编译的程序。

ubuntu@ip-175-76-22-54:~/Documents/VectorClassDemo50/net5.0$ sudo /root/.dotnet/dotnet ./VectorClassDemo50.dll
VectorClassDemo50

IsRelease:	True
EnvironmentVariable(PROCESSOR_IDENTIFIER):	
Environment.ProcessorCount:	2
Environment.Is64BitOperatingSystem:	True
Environment.Is64BitProcess:	True
Environment.OSVersion:	Unix 5.15.0.1023
Environment.Version:	5.0.17
RuntimeEnvironment.GetRuntimeDirectory:	/root/.dotnet/shared/Microsoft.NETCore.App/5.0.17/
RuntimeInformation.FrameworkDescription:	.NET 5.0.17
BitConverter.IsLittleEndian:	True
IntPtr.Size:	8
Vector.IsHardwareAccelerated:	True
Vector<byte>.Count:	16	# 128bit
Vector<T>.Assembly.CodeBase:	file:///root/.dotnet/shared/Microsoft.NETCore.App/5.0.17/System.Private.CoreLib.dll

[Intrinsics.Arm]
AdvSimd.IsSupported:	True
AdvSimd.Arm64.IsSupported:	True
Aes.IsSupported:	True
Aes.Arm64.IsSupported:	True
ArmBase.IsSupported:	True
ArmBase.Arm64.IsSupported:	True
Crc32.IsSupported:	True
Crc32.Arm64.IsSupported:	True
Dp.IsSupported:	False
Dp.Arm64.IsSupported:	False
Rdm.IsSupported:	False
Rdm.Arm64.IsSupported:	False
Sha1.IsSupported:	True
Sha1.Arm64.IsSupported:	True
Sha256.IsSupported:	True
Sha256.Arm64.IsSupported:	True

-- Single, Vector<Single>.Count=4 --
srcT:	<-3.4028235E+38, Infinity, NaN, -1.2>	# (FF7FFFFF 7F800000 FFC00000 BF99999A)
srcAllOnes:	<NaN, NaN, NaN, NaN>	# (FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF)
Abs(srcT):	<3.4028235E+38, Infinity, NaN, 1.2>	# (7F7FFFFF 7F800000 7FC00000 3F99999A)

发现用 .NET 5.0 运行时,部分ARM内在函数是不被支持的,例如 Dp、Rdm。
而之前查看 cpuinfo信息 时,Features里有 asimddp、asimdrdm,且刚才用 .NET 7.0 测试时是支持的。看来硬件是支持的,只是 .NET 5.0 软件不支持而已。
即:虽然 .NET 5.0 定义了ARM内在函数,但是在某些平台上的.NET 5.0运行时,没能支持所有的内在函数。直到 .NET 7.0,才全部解决了内在函数的支持性问题。

参考文献

posted on 2022-11-28 22:36  zyl910  阅读(1431)  评论(1编辑  收藏  举报