具有 SSE4.1 内在函数的双线性滤波器

2024-01-17

我现在正在尝试找出一种一次仅针对一个过滤样本的相当快速的双线性过滤函数,作为习惯使用内在函数的练习 - 最高可达 SSE41 就可以了。

到目前为止我有以下内容:

inline __m128i DivideBy255_8xUint16(const __m128i value)
{
    //  Blinn 16bit divide by 255 trick but across 8 packed 16bit values
    const __m128i plus128 = _mm_add_epi16(value, _mm_set1_epi16(128));
    const __m128i plus128ThenDivideBy256 = _mm_srli_epi16(plus128, 8);          //  TODO:   Should this be an arithmetic or logical shift or does it matter?
    const __m128i partial = _mm_add_epi16(plus128, plus128ThenDivideBy256);
    const __m128i result = _mm_srli_epi16(partial, 8);                          //  TODO:   Should this be an arithmetic or logical shift or does it matter?


    return result;
}


inline uint32_t BilinearSSE41(const uint8_t* data, uint32_t pitch, uint32_t width, uint32_t height, float u, float v)
{
    //  TODO:   There are probably intrinsics I haven't found yet to avoid using these?
    //  0x80 is high bit set which means zero out that component
    const __m128i unpack_fraction_u_mask = _mm_set_epi8(0x80, 0, 0x80, 0, 0x80, 0, 0x80, 0, 0x80, 0, 0x80, 0, 0x80, 0, 0x80, 0);
    const __m128i unpack_fraction_v_mask = _mm_set_epi8(0x80, 1, 0x80, 1, 0x80, 1, 0x80, 1, 0x80, 1, 0x80, 1, 0x80, 1, 0x80, 1);
    const __m128i unpack_two_texels_mask = _mm_set_epi8(0x80, 7, 0x80, 6, 0x80, 5, 0x80, 4, 0x80, 3, 0x80, 2, 0x80, 1, 0x80, 0);


    //  TODO:   Potentially wasting two channels of operations for now
    const __m128i size = _mm_set_epi32(0, 0, height - 1, width - 1);
    const __m128 uv = _mm_set_ps(0.0f, 0.0f, v, u);

    const __m128 floor_uv_f = _mm_floor_ps(uv);
    const __m128 fraction_uv_f = _mm_sub_ps(uv, floor_uv_f);
    const __m128 fraction255_uv_f = _mm_mul_ps(fraction_uv_f, _mm_set_ps1(255.0f));
    const __m128i fraction255_uv_i = _mm_cvttps_epi32(fraction255_uv_f);    //  TODO:   Did this get rounded correctly?

    const __m128i fraction255_u_i = _mm_shuffle_epi8(fraction255_uv_i, unpack_fraction_u_mask); //  Splat fraction_u*255 across all 16 bit words
    const __m128i fraction255_v_i = _mm_shuffle_epi8(fraction255_uv_i, unpack_fraction_v_mask); //  Splat fraction_v*255 across all 16 bit words

    const __m128i inverse_fraction255_u_i = _mm_sub_epi16(_mm_set1_epi16(255), fraction255_u_i);
    const __m128i inverse_fraction255_v_i = _mm_sub_epi16(_mm_set1_epi16(255), fraction255_v_i);

    const __m128i floor_uv_i = _mm_cvttps_epi32(floor_uv_f);
    const __m128i clipped_floor_uv_i = _mm_min_epu32(floor_uv_i, size); //  TODO:   I haven't clamped this probably if uv was less than zero yet...


    //  TODO:   Calculating the addresses in the SSE register set would maybe be better

    int u0 = _mm_extract_epi32(floor_uv_i, 0);
    int v0 = _mm_extract_epi32(floor_uv_i, 1);


    const uint8_t* row = data + (u0<<2) + pitch*v0;


    const __m128i row0_packed = _mm_loadl_epi64((const __m128i*)data);
    const __m128i row0 = _mm_shuffle_epi8(row0_packed, unpack_two_texels_mask);

    const __m128i row1_packed = _mm_loadl_epi64((const __m128i*)(data + pitch));
    const __m128i row1 = _mm_shuffle_epi8(row1_packed, unpack_two_texels_mask);


    //  Compute (row0*fraction)/255 + row1*(255 - fraction)/255 - probably slight precision loss across addition!
    const __m128i vlerp0 = DivideBy255_8xUint16(_mm_mullo_epi16(row0, fraction255_v_i));
    const __m128i vlerp1 = DivideBy255_8xUint16(_mm_mullo_epi16(row1, inverse_fraction255_v_i));
    const __m128i vlerp = _mm_adds_epi16(vlerp0, vlerp1);

    const __m128i hlerp0 = DivideBy255_8xUint16(_mm_mullo_epi16(vlerp, fraction255_u_i));
    const __m128i hlerp1 = DivideBy255_8xUint16(_mm_srli_si128(_mm_mullo_epi16(vlerp, inverse_fraction255_u_i), 16 - 2*4));
    const __m128i hlerp = _mm_adds_epi16(hlerp0, hlerp1);


    //  Pack down to 8bit from 16bit components and return 32bit ARGB result
    return _mm_extract_epi32(_mm_packus_epi16(hlerp, hlerp), 0);
}

该代码假设图像数据为 ARGB8,并且具有额外的列和行来处理边缘情况,而无需分支。

我正在寻求有关我可以使用哪些指令来缩小这个细长混乱的大小的建议,当然还有如何改进它以运行得更快!

谢谢 :)


关于您的代码没有什么具体可说的。但我使用 SSE2 编写了自己的双线性缩放代码。请参阅 StackOverflow 问题帮助我改进更多 SSE2 代码 https://stackoverflow.com/questions/5124608/help-me-improve-some-more-sse2-code更多细节。

在我的代码中,我首先计算水平和垂直分数和索引,而不是每个像素。我认为这样更快。

我在 core2 cpu 下的代码似乎受内存限制而不是 cpu 限制,因此不进行预计算可能会更快。

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

具有 SSE4.1 内在函数的双线性滤波器 的相关文章

  • 如何验证文件名称在 Windows 中是否有效?

    是否有一个 Windows API 函数可以将字符串值传递给该函数 该函数将返回一个指示文件名是否有效的值 我需要验证文件名是否有效 并且我正在寻找一种简单的方法来完成此操作 而无需重新发明轮子 我正在直接使用 C 但针对的是 Win32
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • gcc 与 clang:符号剥离

    gcc 和 AMD Open64 opencc 都有一个 s选项 剥离符号表和重定位信息 到目前为止我还没能在 Clang LLVM 中找到相同的选项 它存在吗 您可以使用stripbinutils 中的实用程序 实际上 llvm ld 有
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • C++ 2.5 字节(20 位)整数

    我知道这很荒谬 但我需要它来优化存储 有什么好的方法用C 实现吗 它必须足够灵活 以便我可以将它用作普通数据类型 例如Vector lt int20 gt 运算符重载等 如果存储是您主要关心的问题 我怀疑您需要相当多的 20 位变量 将它们
  • 如何使用 Jquery 编写“如果未单击”或“如果在元素外部单击”?

    我有点陷入如何阻止菜单执行 fadeOut 函数的问题 当我单击菜单上的主链接打开子菜单时 它就会淡出 目前代码如下 a main menu item click function if rtmenu visible rtmenu clic
  • 从字节数组创建 8 位图像

    字节数组是这样获得的 BufferedImage image new Robot createScreenCapture new Rectangle screenDimension byte array DataBufferByte get
  • 目录最后修改日期

    我想知道目录上次修改日期何时更改 我修改了特定目录中的文件 通过 FTP 但该目录的 LMD 没有更改 它应该如何运作 当添加 删除或重命名文件或子目录时 目录本身的 mtime 修改时间 会发生变化 修改目录中文件的内容不会更改目录本身
  • iphone:从相机捕获的图像改变方向

    我制作了一个 iPhone 应用程序来从相机捕获图像并在下一个视图中设置该图像 但问题是图像被旋转了 即风景图像变成肖像 肖像图像变成风景 我参考了很多代码但无法得到解决方案 我的代码是 void btnCapturePressed if
  • rust 中的类型 `` 没有实现什么特征 `core::kinds::Sized` ?

    我预计这会起作用 trait Task
  • Java EE 7 CDI - 注入不起作用,发送 NullPointerException

    我的注射有问题 这是我第一次尝试 我正在使用 Wildfly 和 Java EE 7 我有一个NullPointerException当尝试访问时Authenticator实例在LoginController 我使用maven 我的bean
  • 迄今为止的 MySQL 字符串,具有包含时区说明符的给定格式

    我的数据库中有一个字符串列 Wed Aug 13 17 51 06 GMT 05 30 2014 我可以将其转换为日期并在 where 子句中使用它来获取记录吗 where Timecolumn gt CURDATE 7 请注意 时区说明符
  • 使用 NSBorderlessWindowMask 时出现灰色边框

    每当我尝试使用 NSBorderlessWindowMask 创建自定义窗口并将 NSView 例如 NSImageView 设置为其 contentView 时 我都会在 NSView 周围出现 1px 灰色边框 并且似乎无法摆脱它 我遵
  • 将多个文件中的空格转换为制表符 Sublime Text 2

    有没有办法将所有空格转换为制表符 而不是逐个文件转换 如果我打开一个文件并浏览View gt Indentation gt Convert Indentation to Tabs 它仅更改此文件 我想将整个项目中的缩进转换为制表符 Use
  • 如何在 django 中提供创建的临时文件

    我有一个远程存储项目 当用户请求他的文件时 django 服务器会在本地检索该文件 用于某些处理 并将其存储为临时文件 然后使用 mod x sendfile 将其提供给用户 我当然希望临时文件在提供给用户后被删除 文件指出NamedTem
  • Flutter,如何删除对话框周围的空白?

    我在从服务器获取数据时调用此对话框 该对话框周围有空格 我可以删除对话框周围的空白区域吗 这是我的代码 var bodyProgress new Container decoration new BoxDecoration color Co
  • 使

    我在 SO 上看到过类似的主题 但我的略有不同 我试图让我的父级 DIV 和子级 保持焦点 直到我将注意力从 div 上移开 但这似乎很难完成 This solution https stackoverflow com a 3089045
  • 使用 Cocoa 的 Accessibility API 获取应用程序的 Dock 图标的位置

    如何使用 Accessibility API 获取应用程序的 Dock 图标的位置 找到了 使用这个论坛帖子 http cocoadev com forums discussion 1431 getting dock icon positi
  • Elasticsearch.Net 和超时

    我有一个 4 节点的 Elasticsearch 集群 我有一个 net 控制台应用程序 旨在用来自 sql 的数据填充集群 只要我将添加 或删除 记录的速度保持在相当低的水平 一切都会正常 如果我最终增加线程数 我将从控制台应用程序中看到
  • 无法在 AngularJS 中从控制器设置日期选择器日期

    我正在尝试按按钮创建一个 AngularJS 日期选择器 我在用this http angular ui github io bootstrap datepickerbootstrap ui 控件 该控件可以工作 单击按钮就会弹出 我可以选
  • 通过 Go (go 1.18) 泛型创建类型化值的新对象

    我正在 go 1 18 的 beta 版本中使用泛型 下面示例中的创建函数应该创建新的实例 T 所以 Apple 我尝试使用反射包来实现这一点 但没有运气 你能告诉我如何更改功能吗Create从下面的示例中 它创建了实例T而不是返回 nil
  • 将所有代码从 master 转移到新分支并从 master 中删除代码

    我的代码位于项目的主分支中 我希望代码位于单独的分支中 而不是在主分支中 我可以创建一个新的分支master 但是在创建分支之后 是否可以从主分支中删除所有代码 这样如果我稍后重新调整或将我的新分支合并到主分支中 就不会导致任何问题 谢谢
  • NodeJS javascript 中的异步响应循环

    我有一个使用 Express 4 的 NodeJS API 我使用 Sequelize 连接到数据库 并多次调用一个查询 我想将结果累积到一个数组中 问题是res send不等待循环结束来发送答案 my code router post p
  • 具有 SSE4.1 内在函数的双线性滤波器

    我现在正在尝试找出一种一次仅针对一个过滤样本的相当快速的双线性过滤函数 作为习惯使用内在函数的练习 最高可达 SSE41 就可以了 到目前为止我有以下内容 inline m128i DivideBy255 8xUint16 const m1