- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定一个 2D 4x8 半字节矩阵,表示为 16 字节 uint8_t 数组。对于每一对半字节 i、j,字节计算如下:(j << 4) | i
.
例如,给定以下矩阵:
0 1 2 3 3 7 1 9
4 5 6 7 4 1 6 15
8 9 10 11 3 14 6 11
12 13 14 15 8 10 7 4
表示为:
const uint8_t matrix[] = {
0x10, 0x32, 0x73, 0x91,
0x54, 0x76, 0x14, 0xf6,
0x98, 0xba, 0xe3, 0xb6,
0xdc, 0xfe, 0xa8, 0x47,
};
所需的数组数组将是:
const uint8_t result[] = {
0x40, 0xc8, 0x51, 0xd9,
0x62, 0xea, 0x73, 0xfb,
0x43, 0x83, 0x17, 0xae,
0x61, 0x76, 0xf9, 0x4b,
}
如何实现最有效的功能?扩展到 AVX2 是公平的游戏。
到目前为止,这是我的 C 实现,基于 Nibble shuffling with x64 SIMD .它将矩阵分成两个 64 位输入,解包半字节,打乱它们并重新打包。
__m128i unpack_nibbles(__m128i src) {
__m128i nibbles_hi = _mm_srli_epi64(src, 4);
//Interlave high nibbles with full nibbles [0000 hi, hi lo, ...] and clear high
__m128i unpacked = _mm_unpacklo_epi8(src, nibbles_hi);
return _mm_and_si128(unpacked, _mm_set1_epi8(0xf));
}
void transpose_4x8_nibbles(uint8_t *src, uint8_t *dst) {
uint8_t *src_lo = src + 0x8;
__m128i data_hi = _mm_loadl_epi64((__m128i*)src);
__m128i data_lo = _mm_loadl_epi64((__m128i*)src_lo);
data_hi = unpack_nibbles(data_hi);
data_lo = unpack_nibbles(data_lo);
//Transpose
__m128i transpose_mask = _mm_setr_epi8(0, 0x8, 0x1, 0x9, 0x2, 0xa, 0x3, 0xb, 0x4, 0xc, 0x5, 0xd, 0x6, 0xe, 0x7, 0xf);
data_hi = _mm_shuffle_epi8(data_hi, transpose_mask);
data_lo = _mm_shuffle_epi8(data_lo, transpose_mask);
//Pack nibbles
__m128i pack_mask = _mm_set1_epi16(0x1001);
data_hi = _mm_maddubs_epi16(data_hi, pack_mask); //even bytes are multiplied by 0x10, odd bytes by 0x01
data_lo = _mm_maddubs_epi16(data_lo, pack_mask);
__m128i data = _mm_packus_epi16(data_hi, data_lo);
data = _mm_shuffle_epi8(data, transpose_mask);
_mm_store_si128((__m128i*) dst, data);
}
最佳答案
让我们按如下方式命名半字节(一切都以小端顺序):
X0 Y0 X1 Y1 X2 Y2 X3 Y3
Z0 W0 Z1 W1 Z2 W2 Z3 W3
X4 Y4 X5 Y5 X6 Y6 X7 Y7
Z4 W4 Z5 W5 Z6 W6 Z7 W7
转置后,我们注意到 X
半字节留在低半字节,W
半字节留在高半字节,Y
半字节从高半字节移动到低,Z
半字节从低到高移动:
X0 Z0 X4 Z4
Y0 W0 Y4 W4
X1 Z1 X5 Z5
Y1 W1 Y5 W5
X2 Z2 X6 Z6
Y2 W2 Y6 W6
X3 Z3 X7 Z7
Y3 W3 Y7 W7
这意味着 X
和 W
半字节可以通过简单的 pshufb
正确放置。 Z
半字节都需要向上移动(或乘以 0x10
) Y
半字节需要向下移动(或乘以 code>uint16
由 0x1000
block 并取结果的上半部分)。
一个 block 00 Z0 00 Z4 Y0 00 Y4 00
实际上就像一个32位整数,我们几乎可以直接从Z0 00 Z4 00
和中得到它00 Y0 00 Y4
通过带有 0x10
和 0x1000
的单个 pmaddwd
指令:
00 Z0 00 Z4 Y0 00 Y4 00 = (00 Y0 00 Y4)* 0x1000 + (Z0 00 Z4 00) * 0x10
而这些半字节恰好与X0, X4
和W0, W4
在相同的字节中所以只需要一个pshufb
来安排相应的字节,但不幸的是,如果 Y4>7
我们有一个负整数,这需要再次屏蔽掉一些位(至少,我们可以重新使用相同的掩码)。
总的来说,这个函数应该完成这个工作:
void transpose_4x8_nibbles(uint8_t const *src, uint8_t *dst) {
__m128i const input = _mm_loadu_si128((__m128i const*)src);
__m128i const shuff = _mm_shuffle_epi8(input, _mm_setr_epi8(0, 8, 4, 12, 1, 9, 5, 13, 2, 10, 6, 14, 3, 11, 7, 15));
__m128i const mask = _mm_set1_epi32(0x0f0ff0f0);
__m128i const XW = _mm_andnot_si128(mask, shuff);
__m128i const YZ = _mm_and_si128(mask, shuff);
__m128i const YZ_trans = _mm_madd_epi16(YZ, _mm_set1_epi32(0x00101000));
__m128i const result = _mm_or_si128(XW, _mm_and_si128(mask, YZ_trans));
_mm_storeu_si128((__m128i*)dst, result);
}
Godbolt 演示(由于 pshufb
,只需要 SSSE3):https://godbolt.org/z/c43oTz43r
关于c - 二维半字节矩阵的高效转置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73450997/
我有一个“设置首选项”屏幕。它有一个 ListPreference 和一个 CheckBoxPreference。当我选择 ListPreference 的一项时,我想更改应用程序的日期格式。另外,通
我试图找到创 build 置/配置窗口的示例。单击菜单项中的“选项”操作可启动设置窗口。我想弄清楚如何从主窗口打开第二个窗口。以及新窗口如何将设置信息返回主窗口。尝试使用 QDialog 或一些继承的
我在 Lnux 上有 Qt 应用程序。我想为此创建一个可执行文件/设置以便在 Windows 上分发它并且不需要安装 Qt。我通过包含所有 dll 为此创建了可执行文件但要运行它,用户需要进入文件夹。
我正在尝试创建一个有点动态的 html 类,它根据类末尾包含的数字设置宽度 %。注意:类名将始终以“gallery-item-”开头 示例:div.gallery-item-20 = 20% 宽度 我
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
在我的应用程序中,我想记住一些变量,例如,如果用户登录过一次,那么他们将在下次重新打开应用程序时登录,或者如果他们决定禁用某些提醒,应用程序可以检查该变量是否是错误的,将不再显示该提醒。理想情况下,这
我在 Netbeans 中开发了一个应用程序,它连接到远程计算机的消息队列并发送消息。该应用程序还有其他功能。项目完成后,我清理并构建应用程序,然后 Netbeans 创建一个 jar 文件。 但我的
我创建了一个 Outlook 加载项,需要创建一个设置以使其可分发(我是新手,所以请原谅新手评论) Outlook -2010 Vs -2010 .Net 4.0 我读了一些地方,最简单的方法就是发
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: How to make installer pack of Java swing Application Proje
这个问题肯定已经被很多人解决过很多次了,但是经过几个小时的研究,我仍然没有找到我要找的东西。 我有一个 ExportSettings.settings 文件,其中包含一堆设置( bool 值、字符串、
我想为我的项目创建一个安装程序,以便它可以安装在任何电脑上而无需安装头文件。我怎样才能做到这一点? 最佳答案 一般有两种分发程序的方法: 源代码分发(要构建的源代码)。最常见的方法是使用 GNU au
如何在这样的动态壁纸中创 build 置 Activity ? Example Picture 我只用一个简单的文本构建了设置 Activity ,但遇到了一些问题。第一个问题是我不能为此 Activ
我用 GUI 创建了一个简单的软件。它有几个源文件。我可以在我的编辑器中运行该项目。我认为它已经为 1.0 版本做好了准备。但我不知道如何为我的软件创 build 置/安装程序。 源代码是python
我的 SettingsActivity当前扩展了 Android Studio 生成的类,AppCompatPreferenceActivity扩展 PreferenceActivity . Acti
我正在使用 .NET 为 IE 开发工具栏。目前,我使用 gacutil 插入我的 .NET 程序集,并使用 regasm 注册我的 COM 程序集。 我想为项目创建一个设置 (MSI),但我似乎无法
在为设置页面创建 Activity 后,我注意到 if (mCurrentValue !== value) 中的 mCurrentValue !== value 返回警告: Identity equa
我在 Visual Studio 10 中创建了一个项目,该项目使用 Mysql 数据库和 Crystalreports 以及 它。但是我不知道如何进行自动安装 Mysql 和 Crystalrepo
我正在尝试在我的 C# 项目中使用 Sqlite 数据库,并且我在 IDE 中做得很好。我的问题是当我为我的项目制作安装包并安装它时,程序无法访问 sqlite 数据库。我也知道这是因为用户没有访问文
我有一个大型 Web 应用程序(带有 11 子系统的 ErP),我想使用 Microsoft WebPI 为它创建一个设置。 目前,我们每周向客户发送一次应用程序(用于每周更新)。 我们在此应用程序中
所以我对工资单申请的最终查询是 - 如何为薪资申请创 build 置? 我需要知道的一切- 如何将设置项目添加到我现有的解决方案 如何将解决方案中的文件添加到安装项目中,以及添加哪些文件添加和在什么文
我是一名优秀的程序员,十分优秀!