SSE、内在函数和对齐

2024-04-26

我使用大量 SSE 编译器内在函数编写了一个 3D 矢量类。一切都工作正常,直到我开始使用 new 来实例化具有 3D 向量作为成员的类。我在发布模式下经历了奇怪的崩溃,但在调试模式下却没有,反之亦然。

因此,我阅读了一些文章,并认为我需要将拥有 3D 矢量类实例的类也对齐到 16 字节。所以我刚刚添加了_MM_ALIGN16 (__declspec(align(16))在类前面,如下所示:

_MM_ALIGN16 struct Sphere
{
    // ....

    Vector3 point;
    float radius
};

起初这似乎解决了问题。但是在更改了一些代码之后,我的程序再次开始以奇怪的方式崩溃。我又在网上搜索了一下,发现了一个blog http://ernsthot.blogspot.de/2009/03/diving-into-sse-alignment-issues.html文章。我尝试了作者 Ernst Hot 所做的方法来解决这个问题,它也对我有用。我向我的类添加了新的和删除的运算符,如下所示:

_MM_ALIGN16 struct Sphere
{
    // ....

    void *operator new (unsigned int size)
     { return _mm_malloc(size, 16); }

    void operator delete (void *p)
     { _mm_free(p); }

    Vector3 point;
    float radius
};

恩斯特提到这种方法也会有问题,但他只是链接到一个不再存在的论坛,而没有解释为什么会出现问题。

所以我的问题是:

  1. 定义运算符有什么问题?

  2. 为什么不添加_MM_ALIGN16到类定义就够了吗?

  3. 处理 SSE 内在函数带来的对齐问题的最佳方法是什么?


首先,您必须关心两种类型的内存分配:

  • 静态分配。为了使自动变量正确对齐,您的类型需要正确的对齐规范(例如__declspec(align(16)), __attribute__((aligned(16))),或者你的_MM_ALIGN16)。但幸运的是,只有当类型成员(如果有)给出的对齐要求不充分时,您才需要这样做。所以你不需要这个Sphere,鉴于你的Vector3已经正确对齐。如果你的Vector3包含一个__m128成员(这很可能,否则我建议这样做),那么你甚至不需要它Vector3。因此,您通常不必弄乱编译器特定的对齐属性。

  • 动态分配。简单的部分就讲这么多。问题是,C++ 在最低级别上使用与类型无关的内存分配函数来分配任何动态内存。这仅保证所有标准类型的正确对齐,这些标准类型可能恰好是 16 字节,但不能保证。

    为了弥补这一点,你必须重载内置的operator new/delete实现您自己的内存分配并在后台使用对齐的分配函数而不是旧的malloc。超载operator new/delete本身就是一个主题,但并不像乍一看那么困难(尽管您的示例还不够),您可以在这个优秀的常见问题解答 https://stackoverflow.com/q/7194127/743214.

    不幸的是,您必须为具有任何需要非标准对齐的成员的每种类型执行此操作,在您的情况下Sphere and Vector3。但是,为了使其变得更容易,您可以做的就是为这些运算符创建一个具有适当重载的空基类,然后从该基类派生所有必要的类。

    大多数人有时容易忘记的是标准分配器std::alocator使用全局的operator new对于所有内存分配,因此您的类型无法与标准容器(以及std::vector<Vector3>这种用例并不罕见)。您需要做的是创建自己的标准一致分配器并使用它。但为了方便和安全,实际上更好的是专注于std::allocator对于您的类型(也许只是从您的自定义分配器派生它),以便始终使用它,并且您不需要每次使用时都关心使用正确的分配器std::vector。不幸的是,在这种情况下,您必须再次针对每种对齐类型专门化它,但是一个小的邪恶宏可以帮助解决这个问题。

    此外,您还必须注意使用全局的其他事情operator new/delete而不是您自定义的,例如std::get_temporary_buffer and std::return_temporary_buffer,并在必要时照顾这些人。

不幸的是,我认为还没有更好的方法来解决这些问题,除非您使用的平台本身就与 16 对齐并了解这一点。或者你可能只是让全局超载operator new/delete始终将每个内存块对齐到 16 字节,并且无需关心包含 SSE 成员的每个类的对齐,但我不知道这种方法的含义。在最坏的情况下,它只会导致内存浪费,但话又说回来,您通常不会在 C++ 中动态分配小对象(尽管std::list and std::map可能对此有不同的看法)。

总结一下:

  • 使用以下方法来注意静态内存的正确对齐__declspec(align(16)),但前提是它还没有被任何成员照顾(通常是这种情况)。

  • 超载operator new/delete对于每种类型都有一个具有非标准对齐要求的成员。

  • 制作一个自定义的符合标准的分配器以在对齐类型的标准容器中使用,或者更好的是,专门化std::allocator对于每个对齐类型。


最后一些一般性建议。通常,在执行许多向量运算时,您只能从计算量大的块中的 SSE 中获益。为了简化所有这些对齐问题,特别是照顾包含一个的每个类型的对齐问题Vector3,这可能是一个好方法,创建一个特殊的 SSE 向量类型,并且仅在冗长的计算中使用它,使用普通的非 SSE 向量来存储和成员变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSE、内在函数和对齐 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 重载<<的返回值

    include
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P

随机推荐

  • 如何获取子进程的返回值?

    程序计算从 1 到 N 的数字之和 子进程计算偶数之和 父进程计算奇数之和 我想在父进程中获取子进程的返回值 我怎么做 include
  • 如何从 Twig 中的多维数组中获取值?

    我的数组 strs key id 的 var dump 给出以下结果 array 2 0 gt array 4 8259 gt string 8260 ouvrir 1 8260 gt string 8261 fichier 2 8261
  • 使用 Json.net 解析 JSON

    我正在尝试使用 JSon Net 库解析一些 JSON 该文档似乎有点稀疏 我对如何完成我需要的内容感到困惑 这是我需要解析的 JSON 格式 displayFieldName OBJECT NAME fieldAliases OBJECT
  • 在其他包中使用 main.go 中声明的结构

    我有一个结构体声明于main go如下所示 type Organization struct ID string json id Count int json count node count 我有一个名为configuration并有这样
  • 当鼠标悬停在图标上时,字形会改变颜色

    我怎样才能让它工作 这样当我将鼠标悬停在 li gt a 时 它也会改变我的字形图标上的颜色 我在下面列出了我的 html 和我的内容tryed在CSS中做 但这只会改变它if我将鼠标悬停在字形图标而不是 a 上 和yes我也尝试在我的 a
  • 如何使用 PDF.js 显示 PDF(以 Base64 存储)中的所有页面?

    我正在使用以下脚本使用 PDF js 显示 PDF 但它在画布上没有显示任何内容 你能告诉我我哪里出了问题吗 我尝试在线查找文档 但找不到任何帮助 Model B 是 base64 字符串
  • wpf xceed工具包水印文本框使水印显示直到第一次输入

    默认行为是当文本框获得焦点时水印消失 我想让水印内容仅在用户键入第一个字符时消失 然后在清除文本后重新出现 有人有好的方法来实现这一点吗 我已经为你调整了默认样式 现在 水印默认显示为 稍暗 默认系统 非活动文本 颜色 并且当水印接收焦点但
  • 使用 @Valid 进行 Spring 验证

    我正在验证传入属性 但验证器甚至捕获未注释的其他页面 Valid RequestMapping value showMatches spr method RequestMethod GET public ModelAndView showM
  • 如何从存储库中删除 Sonatype Nexus OSS(3) 组件

    这是我的第一个问题 我尽力做到最好 如果有什么问题 请简单地告诉我 我会纠正自己 我是 Sonatypes Nexus 3 OSS 的新手 我找不到从我的存储库中删除组件的方法 我的存储库中的一个包已变得无用 现在我想将其删除 我已经删除了
  • spring data neo4j 5 - 没有名为“sessionFactory”的bean可用

    我正在使用 spring data neo4j 5 0 7 RELEASE 和 spring 5 0 6 RELEASE 使用文档中的配置https github com spring projects spring data neo4j
  • 如何让 G1 打印更多日志详细信息?

    我正在测试基于 Jetty 的 API 与基于 Netty 的 API 实验中唯一的区别是我使用哪个 API 相同的应用程序 相同的服务器 相同的内存配置 相同的负载等 我使用基于 Netty 的 API 时会得到更长的 GC 暂停 大多数
  • React Native 上的 MQTT?

    将 MQTT 添加到我的反应原生项目时 我很难找到正确的方法 该项目需要在 iOS 和 Android 上运行 因此理想情况下 MQTT 可以在 javascript 端处理 我意识到移动节点和经典节点的网络巢穴是不同的 所以我开始沿着分叉
  • 自定义 Windows 7 登录 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我如何为 Windows 7 登录屏幕进行编程 不仅仅是替换背景图像 就像我希望它通过 RFID 阅读器进行身份验证一样 我能做到吗 我知道 XP 可
  • 经济模拟的算法?

    我想创建一个游戏 玩家可以创建不同价格的不同产品 称为报价 然后我给他们一定数量的客户 称为需求 现在 我想要一个算法来确定每个参与者的市场份额 当然 我现在就可以使用随机的方式来制作我的 但在这样做之前 我更愿意先问一下 因为我确信在我之
  • 我可以在css中指定maxlength吗?

    我可以用 CSS 中的某些内容替换 maxlength 属性吗
  • 如何根据文件名将文件移动到不同的目录?

    好的 我创建了一个程序 它将根据创建日期重命名目录中的文件 我现在需要能够根据创建日期将这些文件移动到不同的目录中 20131202 1 jpg 将进入名为 20131202 的文件夹 名为 20131203 2 jpg 的文件将进入名为
  • 如何在ios中获取今天日期的开始和结束时间? [复制]

    这个问题在这里已经有答案了 我使用此代码获取当前日期和时间 let today NSDate NSDate let dateFormatter NSDateFormatter NSDateFormatter dateFormatter ti
  • 多个网站,单点登录设计[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我有个问题 我最近一直在做一些工作的一个客户有一系列具有不同登录机制的网站 他正在寻求慢慢迁移到单点登录他的网站机制 全部写在asp net m
  • 使用 Nodejs 和 body-parser 发布表单数据

    我现在已经进行了几次不同的在线尝试 但我的帖子数据一直未定义 并且 console log JSON stringify req body 也没有返回任何内容 所以我在某个地方出错了 HTML
  • SSE、内在函数和对齐

    我使用大量 SSE 编译器内在函数编写了一个 3D 矢量类 一切都工作正常 直到我开始使用 new 来实例化具有 3D 向量作为成员的类 我在发布模式下经历了奇怪的崩溃 但在调试模式下却没有 反之亦然 因此 我阅读了一些文章 并认为我需要将