- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包含 32 个字节的数组。我需要从这个数组中构建 8 个 4 字节的整数。例如0x00,0x11,0x22,0x33 8 位整数需要是一个 0x00112233 32 位整数。我决定使用 AVX 指令,因为我可以使用一个命令将整个数组加载到一个寄存器。
我写的代码:
#include <stdio.h>
#include "immintrin.h"
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
main() {
const uint8_t block[32] __attribute((aligned(32))) = {
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
};
uint32_t m[8] __attribute((aligned(32)));
__m256i ymm9 = _mm256_set_epi8(
block[ 0],block[ 1],block[ 2],block[ 3],block[ 4],block[ 5],block[ 6],block[ 7],
block[ 8],block[ 9],block[10],block[11],block[12],block[13],block[14],block[15],
block[16],block[17],block[18],block[19],block[20],block[21],block[22],block[23],
block[24],block[25],block[26],block[27],block[28],block[29],block[30],block[31]);
_mm256_store_si256(&(m[0]),ymm9);
int i;
for(i=0;i<32;++i) printf("i=%d, 0x%02x\n",i,block[i]);
for(i=0;i<8;++i) printf("i=%d, 0x%08x\n",i,m[i]);
}
您认为它在性能方面是最优的吗?能不能做得更好,跑得更快?我使用 Linux @x86_64 和 gcc 4.8.2。
我是英特尔内在函数领域的初学者。感谢您的帮助。
最佳答案
像往常一样,检查反汇编。然后事实证明,无论如何我使用的编译器,它依赖于该数据是一个编译时间常数,并且它重新排列它以便它可以轻松加载。如果在您的真实代码中确实是这种情况,那很好(但是为什么不使用一组 uint 开始呢?)。但是,如果正如我所怀疑的那样,这只是一个示例,而实际的数组是可变的,那么这就是一场灾难,看看它:
movzx eax, BYTE PTR [rsp+95]
xor ebx, ebx
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+93]
vmovd xmm7, DWORD PTR [rsp]
vpinsrb xmm7, xmm7, BYTE PTR [rsp+94], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+91]
vmovd xmm3, DWORD PTR [rsp]
vpinsrb xmm3, xmm3, BYTE PTR [rsp+92], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+89]
vmovd xmm1, DWORD PTR [rsp]
vpinsrb xmm1, xmm1, BYTE PTR [rsp+90], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+87]
vmovd xmm6, DWORD PTR [rsp]
vpunpcklwd xmm3, xmm7, xmm3
vpinsrb xmm6, xmm6, BYTE PTR [rsp+88], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+85]
vmovd xmm5, DWORD PTR [rsp]
vpinsrb xmm5, xmm5, BYTE PTR [rsp+86], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+83]
vmovd xmm2, DWORD PTR [rsp]
vpunpcklwd xmm1, xmm1, xmm6
vpinsrb xmm2, xmm2, BYTE PTR [rsp+84], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+81]
vmovd xmm0, DWORD PTR [rsp]
vpunpckldq xmm1, xmm3, xmm1
vpinsrb xmm0, xmm0, BYTE PTR [rsp+82], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+79]
vmovd xmm4, DWORD PTR [rsp]
vpunpcklwd xmm2, xmm5, xmm2
vpinsrb xmm4, xmm4, BYTE PTR [rsp+80], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+77]
vmovd xmm8, DWORD PTR [rsp]
vpinsrb xmm8, xmm8, BYTE PTR [rsp+78], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+75]
vpunpcklwd xmm0, xmm0, xmm4
vmovd xmm4, DWORD PTR [rsp]
vpinsrb xmm4, xmm4, BYTE PTR [rsp+76], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+73]
vpunpckldq xmm0, xmm2, xmm0
vmovd xmm2, DWORD PTR [rsp]
vpinsrb xmm2, xmm2, BYTE PTR [rsp+74], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+71]
vmovd xmm7, DWORD PTR [rsp]
vpunpcklqdq xmm1, xmm1, xmm0
vpunpcklwd xmm4, xmm8, xmm4
vpinsrb xmm7, xmm7, BYTE PTR [rsp+72], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+69]
vmovd xmm6, DWORD PTR [rsp]
vpinsrb xmm6, xmm6, BYTE PTR [rsp+70], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+67]
vmovd xmm0, DWORD PTR [rsp]
vpunpcklwd xmm2, xmm2, xmm7
vpinsrb xmm0, xmm0, BYTE PTR [rsp+68], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+65]
vmovd xmm5, DWORD PTR [rsp]
vpunpckldq xmm2, xmm4, xmm2
vpinsrb xmm5, xmm5, BYTE PTR [rsp+66], 1
mov BYTE PTR [rsp], al
vmovd xmm3, DWORD PTR [rsp]
vpunpcklwd xmm0, xmm6, xmm0
vpinsrb xmm3, xmm3, BYTE PTR [rsp+64], 1
vpunpcklwd xmm3, xmm5, xmm3
vpunpckldq xmm0, xmm0, xmm3
vpunpcklqdq xmm0, xmm2, xmm0
vinserti128 ymm0, ymm1, xmm0, 0x1
vmovdqa YMMWORD PTR [rsp+32], ymm0
哇。好吧,不太好。确实比没有内在函数做同样的事情更糟糕,但并非所有都丢失了。最好将数据加载为 little endian uint,然后用 _mm256_shuffle_epi8
交换它们,有点像这样(但检查随机播放掩码,我没有测试它)
__m256i ymm9 = _mm256_shuffle_epi8(_mm256_load_si256((__m256i*)block), _mm256_set_epi8(
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15));
ymm9 = _mm256_permute2x128_si256(ymm9, ymm9, 1);
_mm256_store_si256((__m256i*)m, ymm9);
一般来说,要非常小心“set”系列的内在函数,它们可以编译成非常糟糕的指令序列。
关于c - 如何使用英特尔内部函数从 8 位整数数组构建 32 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30492092/
这是我的测试用例。 http://tobeythorn.com/isi/dummy2.svg http://tobeythorn.com/isi/isitest.html 如果我自己打开 svg,内部
这是我的测试用例。 http://tobeythorn.com/isi/dummy2.svg http://tobeythorn.com/isi/isitest.html 如果我自己打开 svg,内部
我正在尝试做类似的事情: SELECT SUM( CASE WHEN ( AND EXISTS(SELECT 1
我想问如何在外部 ng-repeat 内部正确使用内部 ng-repeat: 这意味着你想使用这样的东西: {{milestone.id}} {{
我希望在 wordpress 的仪表板内编辑 css 样式并且如果可能的话不必编辑 php 文件。 我知道至少可以编辑一些属性,所以我希望我可以直接在仪表板中编辑所有属性。 更具体地说如何更改自定义类
我在安装在 windows10 上的 vmware 中的 Ubuntu 上安装了伪分布式独立 hadoop 版本。 我从网上下载了一个文件,复制到ubuntu本地目录/lab/data 我在 ubun
我有一个如下所示的 WHERE 语句: WHERE ((@Value1 IS NULL AND [value1_id] IS NULL) OR [value1_id] = ISNULL(@Va
我有一个如下所示的 WHERE 语句: WHERE ((@Value1 IS NULL AND [value1_id] IS NULL) OR [value1_id] = ISNULL(@Va
在我的一些测试帮助程序代码中,我有一个名为 FakeDbSet(Of T) 的 IDbSet(Of T) 实现,它模拟了许多 EF 行为,但没有实际的数据库。我将类声明为 Friend ,因为我想强制
我正在寻找 Cassandra/CQL 的常见 SQL 习语 INSERT INTO ... SELECT ... FROM ... 的表亲。并且一直无法找到任何以编程方式或在 CQL 中执行此类操作
如何防止内部 while 循环无限运行?问题是,如果没有外部 while 循环,内部循环将毫无问题地运行。我知道它必须对外循环执行某些操作,但我无法弄清楚是什么导致了问题。 import java.u
我正在努力学习更多有关 C++ 的知识,但在国际象棋程序中遇到了一些代码,需要帮助才能理解。我有一个 union ,例如: union b_union { Bitboard b; st
这是我项目网页中的代码片段。这里我想显示用户选择的类别,然后想显示属于该类别的主题。在那里,用户可以拥有多个类别,这没有问题。我可以在第一个 while 循环中打印所有这些类别。问题是当我尝试打印主题
我想知道如何在 swing 中显示内部框架。这意味着,当需要 JFrame 时,通常我所做的是, new MyJFrame().setVisible(true); 假设之前的表单也应该显示。当显示这个
我最近发现了一些有趣的行为,这让我想知道对象如何知道存在哪些全局变量。例如,假设我有一个文件“test.py”: globalVar = 1 toDelete = 2 class Test(objec
我知道它已经在这里得到回答: google maps drag and drop objects into google maps from outside the Map ,但这并不完全是我所需要的
我目前正在学习Javascript DOM和innerHTML,发现在理解innerHTML方面存在一些问题。 这是我的代码:http://jsfiddle.net/hphchan/bfjx1w70/
我构建了一个布局如下的库: lib/ private_class_impl.cc private_class_decl.h public_class_impl.cc include/
我有一个使用 bootstrap 3 的组合 wordpress 网站。它基本上是一个图像网格。当屏幕展开时,它会从三列变为四列。移动时它是一列。 我想出了如何调整图像的顶部和底部边距,但我希望图像的
我正在试用 MSP-EXP430G2 的教程程序,使用 Code Composer Studio 使 LED 闪烁。最初,它有一个闪烁的无限循环: for(;;) // This emp
我是一名优秀的程序员,十分优秀!