You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ada 2012中定义__m256i数据类型?AVX2开发咨询

在GNAT Ada中实现AVX2整数向量加法

实现思路反馈

你的三步实现逻辑是完全正确的,符合AVX2 intrinsic的常规使用流程。需要注意几个细节:

  • 你代码里的pragma Pack(Vec_256_Integer_32);参数写错了,应该是Vector_256_Integer_32
  • 第三步提到的转换回Vec_256_Unsigned_32是笔误,应该对应Vector_256_Integer_32类型
  • 加载/存储时要确保数组的32字节对齐,除了依赖你已有的对齐设置,也可以在类型定义时显式加上pragma Alignment(32);来强化对齐要求

Ada中__m256i类型的定义

GNAT支持通过pragma Machine_Attribute来模拟GCC的__vector_size__和__may_alias__属性,对应__m256i的Ada类型可以这样定义:

with Interfaces.C; use Interfaces.C;

type M256i is array (0 .. 3) of Long_Long_Integer;
pragma Machine_Attribute (M256i, "vector_size", "32");
pragma Machine_Attribute (M256i, "may_alias");

这个类型和GCC的__m256i二进制完全兼容,都是32字节的向量类型,且允许别名访问内存区域。

完整的加法函数实现

结合你的思路,完整的实现代码如下:

with Interfaces.C; use Interfaces.C;
with System.Storage_Elements; use System.Storage_Elements;

package AVX2_Integers is
   type Integer_32 is new Interfaces.Integer_32;

   type Vector_256_Integer_32 is array (0 .. 7) of Integer_32;
   pragma Pack(Vector_256_Integer_32);
   pragma Alignment(32, Vector_256_Integer_32); -- 显式指定32字节对齐

   type M256i is array (0 .. 3) of Long_Long_Integer;
   pragma Machine_Attribute (M256i, "vector_size", "32");
   pragma Machine_Attribute (M256i, "may_alias");

   -- 绑定GCC的AVX2 intrinsics函数
   function MM256_Load_Si256 (Ptr : access constant M256i) return M256i
     with Import, Convention => C, External_Name => "_mm256_load_si256";

   function MM256_Add_Epi32 (A, B : M256i) return M256i
     with Import, Convention => C, External_Name => "_mm256_add_epi32";

   procedure MM256_Store_Si256 (Ptr : access M256i; Value : M256i)
     with Import, Convention => C, External_Name => "_mm256_store_si256";

   function Vector_256_Integer_32_Add (Left, Right : Vector_256_Integer_32) return Vector_256_Integer_32;
end AVX2_Integers;

package body AVX2_Integers is
   function Vector_256_Integer_32_Add (Left, Right : Vector_256_Integer_32) return Vector_256_Integer_32 is
      Result : Vector_256_Integer_32;
      -- 通过Address属性实现类型指针转换,绕过Ada强类型检查
      Left_M256i : constant access constant M256i := M256i'(others => 0)'Access with Address => Left'Address;
      Right_M256i : constant access constant M256i := M256i'(others => 0)'Access with Address => Right'Address;
      Result_M256i : access M256i := M256i'(others => 0)'Access with Address => Result'Address;
      Temp : M256i;
   begin
      -- 加载左右操作数到AVX寄存器
      Temp := MM256_Load_Si256 (Left_M256i);
      Temp := MM256_Add_Epi32 (Temp, MM256_Load_Si256 (Right_M256i));
      -- 将结果从寄存器存储回数组
      MM256_Store_Si256 (Result_M256i, Temp);
      return Result;
   end Vector_256_Integer_32_Add;
end AVX2_Integers;

额外注意事项

  • 编译时必须启用AVX2优化,添加编译选项-mavx2 -O2才能让GNAT生成正确的AVX2指令
  • 如果你已经通过其他方式(比如内存分配时的对齐设置)保证了数组的32字节对齐,可以保留现有设置,pragma Alignment作为可选强化项
  • 代码中通过Address属性实现的类型转换,对应GCC__may_alias__的功能,确保可以用不同类型访问同一块内存

内容的提问来源于stack exchange,提问作者user20790983

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 07:50:18