Vulkan规范:第八章 8.2 ~ 8.3

本文探讨了图形管线中着色器的执行顺序及内存访问特性,详细解析了不同阶段着色器调用间的相对顺序及内存访问的不确定性,并介绍了如何使用内存屏障指令保证数据的一致性。

8.2. 着色器的执行

在管线的每一个阶段,对着色器的多次调用可能同时执行。 甚至,多个命令都调用的单个着色器也可以同时执行。 调用同一个着色器类型所产生的相对执行顺序也是未知的。 应用程序绘制命令或者分发命令产生的图元的顺序和着色器调用完成的顺序也可能不一致。 然而,片元着色器输出到附件依栅格化顺序

不同着色器类型调用的相对顺序基本上是未定义的。 然而,当调用的着色器的输入是前一个管线阶段的输出时,可以保证前一个阶段在产生所有必需的输入信息之前已经完成了。

8.3. 着色器内存访问顺序

着色器读取或者写入图像或缓冲区的顺序基本上是未定义的。 对于一些着色器类型(顶点、细分求值和某些情况下的片元着色器),甚至是可能进行加载和存储的着色器调用的次数也是未定义的。

尤其是以下规则应用时:

  • 对于每一个不同的顶点,Vertex 和 tessellation evaluation 着色器将被至少调用一次。

  • Fragment 着色器将被调用0次或者多次。

  • 同类型的着色器的相对调用顺序是未定义的。 A store issued by a shader when working on primitive B might complete prior to a store for primitive A, even if primitive A is specified prior to primitive B. This applies even to fragment shaders; while fragment shader outputs are always written to the framebuffer in rasterization order, stores executed by fragment shader invocations are not.

  • 不同类型着色器程序的相对调用顺序基本上是未定义的。

注意

上述的对于着色器调用的顺序的限制形成了在一系列的不可能实现的图元上着色器调用之间的同步。 For example, having one invocation poll memory written by another invocation assumes that the other invocation has been launched and will complete its writes in finite time.

Stores issued to different memory locations within a single shader invocation may not be visible to other invocations, or may not become visible in the order they were performed.

The OpMemoryBarrier instruction can be used to provide stronger ordering of reads and writes performed by a single invocation. OpMemoryBarrier guarantees that any memory transactions issued by the shader invocation prior to the instruction complete prior to the memory transactions issued after the instruction. Memory barriers are needed for algorithms that require multiple invocations to access the same memory and require the operations to be performed in a partially-defined relative order. For example, if one shader invocation does a series of writes, followed by an OpMemoryBarrier instruction, followed by another write, then the results of the series of writes before the barrier become visible to other shader invocations at a time earlier or equal to when the results of the final write become visible to those invocations. In practice it means that another invocation that sees the results of the final write would also see the previous writes. Without the memory barrier, the final write may be visible before the previous writes.

Writes that are the result of shader stores through a variable decorated with Coherent automatically have available writes to the same buffer, buffer view, or image view made visible to them, and are themselves automatically made available to access by the same buffer, buffer view, or image view. Reads that are the result of shader loads through a variable decorated with Coherent automatically have available writes to the same buffer, buffer view, or image view made visible to them. The order that coherent writes to different locations become available is undefined, unless enforced by a memory barrier instruction or other memory dependency.

Example 1. 注意

显式的内存依赖仍然需要使用,来保证对其他缓冲区、缓冲区视图、图像视图的访问的可用性和可见性。

内置的内存事务指令可以用来对给定内存地址读取或者写作的原子性。 当多个着色器调用内置的原子函数互相之间按照未定义的顺序执行时,这些函数都对一个内存地址进行内存读写操作, 且保证没有其他的内存事务将在读写期间对潜在的内存写入。 原子操作像对Coherent变量一样,保证了读写操作的可用性和可见性。

Example 2. 注意

在同一份内存上不同资源描述符进行内存访问,甚至有Coherent修饰符或通过原子操作,也可能是没有良好定义的, 因为诸如图像布局或者资源归属(Synchronization and Cache Control一章中讲解)等原因。

注意

原子操作允许着色器使用共享全局地址作为互斥性或者作为计数器,或其他用途。

欧姆龙FINS(工厂集成网络系统)协议是专为该公司自动化设备间数据交互而设计的网络通信标准。该协议构建于TCP/IP基础之上,允许用户借助常规网络接口执行远程监控、程序编写及信息传输任务。本文档所附的“欧ronFins.zip”压缩包提供了基于C与C++语言开发的FINS协议实现代码库,旨在协助开发人员便捷地建立与欧姆龙可编程逻辑控制器的通信连接。 FINS协议的消息框架由指令头部、地址字段、操作代码及数据区段构成。指令头部用于声明消息类别与长度信息;地址字段明确目标设备所处的网络位置与节点标识;操作代码定义了具体的通信行为,例如数据读取、写入或控制器指令执行;数据区段则承载实际交互的信息内容。 在采用C或C++语言实施FINS协议时,需重点关注以下技术环节: 1. **网络参数设置**:建立与欧姆龙可编程逻辑控制器的通信前,必须获取控制器的网络地址、子网划分参数及路由网关地址,这些配置信息通常记载于设备技术手册或系统设置界面。 2. **通信链路建立**:通过套接字编程技术创建TCP连接至控制器。该过程涉及初始化套接字实例、绑定本地通信端口,并向控制器网络地址发起连接请求。 3. **协议报文构建**:依据操作代码与目标功能构造符合规范的FINS协议数据单元。例如执行输入寄存器读取操作时,需准确配置对应的操作代码与存储器地址参数。 4. **数据格式转换**:协议通信过程中需进行二进制数据的编码与解码处理,包括将控制器的位状态信息或数值参数转换为字节序列进行传输,并在接收端执行逆向解析。 5. **异常状况处理**:完善应对通信过程中可能出现的各类异常情况,包括连接建立失败、响应超时及错误状态码返回等问题的处理机制。 6. **数据传输管理**:运用数据发送与接收函数完成信息交换。需注意FINS协议可能涉及数据包的分割传输与重组机制,因单个协议报文可能被拆分为多个TCP数据段进行传送。 7. **响应信息解析**:接收到控制器返回的数据后,需对FINS响应报文进行结构化解析,以确认操作执行状态并提取有效返回数据。 在代码资源包中,通常包含以下组成部分:展示连接建立与数据读写操作的示范程序;实现协议报文构建、传输接收及解析功能的源代码文件;说明库函数调用方式与接口规范的指导文档;用于验证功能完整性的测试案例。开发人员可通过研究这些材料掌握如何将FINS协议集成至实际项目中,从而实现与欧姆龙可编程逻辑控制器的高效可靠通信。在工程实践中,还需综合考虑网络环境稳定性、通信速率优化及故障恢复机制等要素,以确保整个控制系统的持续可靠运行。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
cmake -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-toolchain.cmake -DCMAKE_INSTALL_PREFIX=${SYSROOT}/usr -DCMAKE_CXX_FLAGS="-O3 -mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard" -DCMAKE_C_FLAGS="-O3 -mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard" -DENABLE_NEON=ON -DENABLE_VFPV3=ON -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_opencv_apps=OFF -DWITH_GTK=OFF .. -- The CXX compiler identification is GNU 11.4.0 -- The C compiler identification is GNU 11.4.0 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - failed -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ - broken CMake Error at /usr/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake:62 (message): The C++ compiler "/usr/bin/c++" is not able to compile a simple test program. It fails with the following output: Change Dir: /home/forlinx/opencv-4.5.5/build/CMakeFiles/CMakeTmp Run Build Command(s):/usr/bin/gmake -f Makefile cmTC_a235a/fast && /usr/bin/gmake -f CMakeFiles/cmTC_a235a.dir/build.make CMakeFiles/cmTC_a235a.dir/build gmake[1]: Entering directory '/home/forlinx/opencv-4.5.5/build/CMakeFiles/CMakeTmp' Building CXX object CMakeFiles/cmTC_a235a.dir/testCXXCompiler.cxx.o /usr/bin/c++ -O3 -mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard -fPIE -o CMakeFiles/cmTC_a235a.dir/testCXXCompiler.cxx.o -c /home/forlinx/opencv-4.5.5/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx c++: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ instead c++: error: unrecognized command-line option ‘-mfpu=neon-vfpv4’ c++: error: unrecognized command-line option ‘-mfloat-abi=hard’ gmake[1]: *** [CMakeFiles/cmTC_a235a.dir/build.make:78: CMakeFiles/cmTC_a235a.dir/testCXXCompiler.cxx.o] Error 1 gmake[1]: Leaving directory '/home/forlinx/opencv-4.5.5/build/CMakeFiles/CMakeTmp' gmake: *** [Makefile:127: cmTC_a235a/fast] Error 2 CMake will not be able to correctly generate this project. Call Stack (most recent call first): CMakeLists.txt:113 (enable_language) -- Configuring incomplete, errors occurred! See also "/home/forlinx/opencv-4.5.5/build/CMakeFiles/CMakeOutput.log". See also "/home/forlinx/opencv-4.5.5/build/CMakeFiles/CMakeError.log".
09-16
<think> 我们正在解决的是在交叉编译OpenCV 4.5.5时,CMake配置阶段C++编译器报错的问题。错误信息显示: - `-mfpu=neon-vfpv4` 不被识别 - `-mfloat-abi=hard` 不被识别 - `-mcpu=` 被警告为已弃用 从错误信息中可以看出,这些编译器选项是针对ARMv7架构的(32位ARM),而我们的目标平台是AArch64(64位ARM)。在AArch64中,NEON是默认包含的,且浮点ABI是固定的(通常是softfp或hard,但在AArch64中,硬件浮点是标准,并且ABI是统一的,不需要特别指定)。另外,`-mfpu`选项在AArch64中无效,因为AArch64的浮点和SIMD单元(NEON)是核心指令集的一部分。 因此,我们需要调整编译选项,去掉那些不适用于AArch64的选项,并采用适用于AArch64的选项。 ### 解决方案 #### 1. 修正编译选项 在AArch64架构下,我们不需要指定`-mfpu`和`-mfloat-abi`,因为: - NEON在AArch64中是必须支持的,且无法禁用。 - 浮点运算使用硬件浮点,且ABI固定。 同时,`-mcpu`选项已被GCC弃用,建议使用`-march`和`-mtune`代替。 因此,我们可以将编译选项修改为: ```bash -DCMAKE_CXX_FLAGS="-O3 -march=armv8-a+simd -mtune=cortex-a72" -DCMAKE_C_FLAGS="-O3 -march=armv8-a+simd -mtune=cortex-a72" ``` 这里: - `-march=armv8-a+simd`:指定目标架构为ARMv8-A,并启用SIMD(即NEON)扩展。实际上,在AArch64中,NEON是默认启用的,但显式指定可以确保。 - `-mtune=cortex-a72`:针对Cortex-A72进行优化。 #### 2. 调整OpenCV的NEON和VFP选项 在AArch64中,NEON是必须的,因此我们不需要特别设置`ENABLE_NEON`(它应该自动开启)。另外,VFPV3是ARMv7的浮点扩展,在AArch64中不存在。因此,我们可以去掉`-DENABLE_VFPV3=ON`。 #### 3. 修改CMake命令 修正后的CMake命令如下: ```bash cmake \ -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-gnu.toolchain.cmake \ -DCMAKE_INSTALL_PREFIX=${SYSROOT}/usr \ -DCMAKE_CXX_FLAGS="-O3 -march=armv8-a+simd -mtune=cortex-a72" \ -DCMAKE_C_FLAGS="-O3 -march=armv8-a+simd -mtune=cortex-a72" \ -DBUILD_TESTS=OFF \ -DBUILD_PERF_TESTS=OFF \ -DBUILD_EXAMPLES=OFF \ -DBUILD_opencv_apps=OFF \ -DWITH_GTK=OFF \ .. ``` #### 4. 检查工具链文件 确保工具链文件`aarch64-gnu.toolchain.cmake`中已经正确设置交叉编译器。例如,它应该包含: ```cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) ``` #### 5. 清理构建目录 在重新运行CMake之前,建议清理构建目录中的`CMakeCache.txt`和`CMakeFiles`,以避免缓存问题: ```bash rm -rf CMakeCache.txt CMakeFiles/ ``` ### 补充说明 - 如果目标设备支持更高级的ARMv8.2或ARMv8.3特性(如FP16),可以升级`-march`为`armv8.2-a+fp16+simd`等。 - OpenCV在检测到AArch64架构时,会自动启用NEON,所以`-DENABLE_NEON=ON`可以去掉,但保留也不会出错。 ### 验证 重新运行CMake后,检查输出日志,确认: - 没有出现之前的错误。 - 检测到NEON并启用。 ### 相关问题 1. 如何根据不同ARM架构(如Cortex-A53、Cortex-A72、Cortex-X1)优化OpenCV编译参数? 2. 在交叉编译OpenCV时,如何处理第三方依赖(如libjpeg-turbo、libpng)以确保正确链接? 3. 如何验证编译后的OpenCV库在目标设备上的兼容性和性能? 4. 在AArch64平台上启用OpenCV的Vulkan加速需要哪些特殊配置? </think> 以下是解决CMake配置OpenCV 4.5.5时编译器无法识别 `-mfpu=neon-vfpv4` 和 `-mfloat-abi=hard` 选项的完整方案: ### 问题根源分析 1. **架构不匹配**: - `-mfpu=neon-vfpv4` 和 `-mfloat-abi=hard` 是 ARMv7(32位)专用选项 - AArch64(64位)使用不同的 SIMD 架构,NEON 已集成在核心指令集中 - OpenCV 4.5.5 的 CMake 配置需要针对 AArch64 优化[^1] 2. **编译器兼容性**: ```log c++: error: unrecognized command-line option ‘-mfpu=neon-vfpv4’ c++: error: unrecognized command-line option ‘-mfloat-abi=hard’ ``` 表明当前编译器不支持这些 ARMv7 专属标志 --- ### 完整解决方案 #### 步骤1:修正编译标志 替换不兼容的 ARMv7 标志为 AArch64 标准选项: ```bash # 原始问题标志 -DCMAKE_CXX_FLAGS="-O3 -mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard" # 修正为AArch64兼容标志 -DCMAKE_CXX_FLAGS="-O3 -march=armv8-a+fp16+simd -mtune=cortex-a72" -DCMAKE_C_FLAGS="-O3 -march=armv8-a+fp16+simd -mtune=cortex-a72" ``` #### 步骤2:更新工具链配置 在 `aarch64-gnu.toolchain.cmake` 中确保包含: ```cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) # 必须指定交叉编译器 set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) # AArch64不需要-mfpu/-mfloat-abi set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a") ``` #### 步骤3:优化OpenCV配置 ```bash cmake \ -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-gnu.toolchain.cmake \ -DCMAKE_INSTALL_PREFIX=${SYSROOT}/usr \ -DCMAKE_CXX_FLAGS="-O3 -march=armv8.2-a+fp16+simd -mtune=cortex-a72" \ -DCMAKE_C_FLAGS="-O3 -march=armv8.2-a+fp16+simd -mtune=cortex-a72" \ -DENABLE_NEON=ON \ # AArch64中NEON默认启用 -DCPU_BASELINE=NEON \ # 显式声明基准指令集 -DWITH_GTK=OFF \ -DBUILD_TESTS=OFF \ -DBUILD_PERF_TESTS=OFF \ -DBUILD_EXAMPLES=OFF \ .. ``` #### 关键参数说明 | 参数 | 值 | 作用 | |------|----|------| | `-march` | `armv8.2-a+fp16+simd` | 启用ARMv8.2指令集+FP16+NEON | | `-mtune` | `cortex-a72` | 针对Cortex-A72微架构优化 | | `ENABLE_NEON` | `ON` | 强制启用NEON SIMD指令 | | `CPU_BASELINE` | `NEON` | 设定最低指令集要求 | > **物理含义**:AArch64架构中,NEON指令集已整合进基础指令集,不再需要单独的浮点单元(FPU)标志。`-march=armv8-a` 已包含完整NEON支持,其计算能力满足: > $$ \text{NEON} \subseteq \text{ARMv8-A} \subseteq \text{ARMv8.2-A} $$ --- ### 验证成功配置 检查CMake输出日志中应包含: ```log -- Found NEON: YES (Required is at least version "1.0") -- CPU/HW features: FP16 NEON -- Target arch: aarch64 ``` ### 故障排查 1. **编译器版本验证**: ```bash aarch64-linux-gnu-gcc -dM -E - < /dev/null | grep -i neon # 应输出 NEON 相关定义 ``` 2. **清除缓存**: ```bash rm -rf CMakeCache.txt CMakeFiles/ ``` 3. **兼容性修复**: ```bash # 解决旧版OpenCV的兼容问题 -DCMAKE_CXX_FLAGS="-Wno-deprecated -Wno-ignored-attributes" ``` > **参考**:交叉编译时建议使用统一工具链,避免混合系统库和交叉编译库[^1] --- ### 相关问题 1. 如何针对不同ARM架构(Cortex-A53/A72/X1)优化OpenCV编译参数? 2. 交叉编译时如何处理OpenCV的第三方依赖(如libjpeg-turbo, libpng)? 3. 如何验证编译后的OpenCV库在目标设备上的兼容性和性能? 4. 在AArch64平台上启用OpenCV的Vulkan加速需要哪些特殊配置?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值