- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发基于Intel指令集(AVX,FMA等)的高性能算法。当数据按顺序存储时,我的算法(内核)运行良好。但是,现在我面临一个大问题,但没有找到解决方法或解决方案:
see 2D Matrix
int x, y; x = y = 4096;
float data[x*y]__attribute__((aligned(32)));
float buffer[y]__attribute__((aligned(32)));
/* simple test data */
for (i = 0; i < x; i++)
for (j = 0; j < y; j++)
data[y*i+j] = y*i+j; // 0,1,2,3...4095, | 4096,4097, ... 8191 |...
/* 1) Extract the columns out of matrix */
__m256i vindex; __m256 vec;
vindex = _mm256_set_epi32(7*y, 6*y, 5*y, 4*y, 3*y, 2*y, y, 0);
for(i = 0; i < x; i+=8)
{
vec = _mm256_i32gather_ps (&data[i*y], vindex, 4);
_mm256_store_ps (buffer[i], vec);
}
/* 2) Perform functions */
fft(buffer, x) ;
/*3) write back buffer into matrix*/
/* strided write??? ...*/
最佳答案
[对于行主要数据,SIMD对行的访问速度快,而对列的访问速度慢]
是的,这就是x86-64和类似体系结构的本质。访问内存中的连续数据很快,但是访问分散的数据(无论是随机的还是规则的模式)的速度都很慢。这是拥有处理器缓存的结果。
有两种基本方法:将数据复制到有助于更好访问模式的新顺序,或者以允许更好访问模式的顺序进行计算。
不,没有经验法则或千篇一律的技巧可以使一切正常。实际上,即使比较不同的实现也很棘手,因为存在许多复杂的交互(从缓存等待时间到操作交错,再到缓存和内存访问模式),因此结果在很大程度上取决于特定的硬件和手头的数据集。
让我们看一下典型的示例情况,矩阵矩阵乘法。假设我们使用标准的C行主要数据顺序将两个5×5矩阵相乘(c = a×b):
c00 c01 c02 c03 c04 a00 a01 a02 a03 a04 b00 b01 b02 b03 b04
c05 c06 c07 c08 c09 a05 a06 a07 a08 a09 b05 b06 b07 b08 b09
c10 c11 c12 c13 c14 = a10 a11 a12 a13 a14 × b10 b11 b12 b13 b14
c15 c16 c17 c18 c19 a15 a16 a17 a18 a19 b15 b16 b17 b18 b19
c20 c21 c22 c23 c24 a20 a21 a22 a23 a24 b20 b21 b22 b23 b24
c00 a00 b00 a01 b05 a02 b10 a03 b15 a04 b20
c01 a00 b01 a01 b06 a02 b11 a03 b16 a04 b21
c02 = a00 × b02 + a01 × b07 + a02 × b12 + a03 × b17 + a04 × b22
c03 a00 b03 a01 b08 a02 b13 a03 b18 a04 b23
c04 a00 b04 a01 b09 a02 b14 a03 b19 a04 b24
c05 a05 b00 a06 b05 a07 b10 a08 b15 a09 b20
c06 a05 b01 a06 b06 a07 b11 a08 b16 a09 b21
c07 = a05 × b02 + a06 × b07 + a07 × b12 + a08 × b17 + a09 × b22
c08 a05 b03 a06 b08 a07 b13 a08 b18 a09 b23
c09 a05 b04 a06 b09 a07 b14 a08 b19 a09 b24
c
与
b
具有相同的顺序,则我们可以将具有连续存储内容的SIMD寄存器用于
c
和
b
,并且仅收集
a
。此外,
a
的SIMD寄存器的所有组件都具有相同的值。
b
寄存器对
c
的所有五行重复。因此,最好将
c
初始化为零,然后对具有相同
b
SIMD寄存器的乘积进行加法运算:
c00 a00 b00 c05 a05 b00 c10 a10 b00 c15 a15 b00 c20 a20 b00
c01 a00 b01 c06 a05 b01 c11 a10 b01 c16 a15 b01 c21 a20 b01
c02 += a00 × b02, c07 += a05 × b02, c12 += a10 × b02, c17 += a15 × b02, c22 += a20 × b02
c03 a00 × b03 c08 a05 b03 c13 a10 b03 c18 a15 b03 c23 a20 b03
c04 a00 × b04 c09 a05 b04 c14 a10 b04 c19 a15 b04 c24 a20 b04
a
,则
a
的SIMD矢量寄存器也将从连续的存储器位置中获取值。实际上,如果
a
足够大,则线性化
a
的内存访问模式也可以提供足够大的速度提升,从而可以更快地进行转置副本(对浮点使用
uint32_t
,对双精度使用
uint64_t
;即完全不使用SIMD或浮点进行转置,而只是按转置顺序复制存储)。
c
和
b
具有相同的数据顺序,而
a
具有相反的数据顺序,则可以有效地对矩阵乘积进行SIMD矢量化,而不必复制任何数据。仅求和是不同的,因为这取决于数据顺序,并且矩阵乘法不是可交换的(a×b!= b×a)。
<x86intrin.h>
),我们在设计内部数据结构时也可以应用上面的逻辑,从而使我们使用的C编译器有最好的机会为我们向量化计算。 (不过,它们还不是很擅长。就像我说的那样,复杂的东西。有些人喜欢Fortran比C强,因为它的表达式和规则使Fortran编译器更容易优化和矢量化它们。)
关于c - SIMD 2D矩阵英特尔指令集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54345489/
我想开始使用一些 AVX(高级矢量扩展)指令。我知道英特尔提供了一个模拟器来测试包含这些指令的软件(请参阅 this question ),但由于我不想手动编写十六进制代码,因此出现了关于 的问题。哪
假设我使用的是基于 Intel x64 的笔记本电脑,没有专用的 GPU。 我必须有一些板载 GPU 否则我的屏幕将无法工作,对吗? 板载 GPU 通常是否嵌入到 CPU 中? 英特尔是否有单独的 G
我遇到了这个错误:“SSE 指令集未启用”。我该如何解决这个问题? 我有 ACER i7,Ubuntu 11.10,请问有人能帮帮我吗? 任何帮助将不胜感激! 同时运行: sudo cat /pro
我希望创建一个最小的、计算通用的字母数字 x86 操作码子集。最终我希望子集包含尽可能少的指令,如果有多个最小子集,我也想知道。该子集应该能够模拟可以用整个字母数字指令集编写的任何程序。说明应仅涵盖与
COM 文件中使用了哪些指令集?我以为是 8086,但似乎我错了。在我发现的 8086 手册中,shl 的第二个参数只能接受 1 或 cl,而 1 以外的立即值对我来说很好用。如果重要,我正在使用 N
在“ARM11TechnicalRefManual”第 1-34 节的“Thumb 指令集”下,它说: “Thumb 指令集是最常用的 32 位 ARM 指令的子集。Thumb 指令长 16 位,并且
Java Virtual Machine Instruction Set页面提供aaload、aastore...等助记词信息 然而,既没有提到这些助记符占用的CPU周期,也没有任何关于这些助记符的字
在任何编程环境中,无论我选择何种数据类型,最终 CPU 都只会执行算术运算(加法/逻辑运算)。 这种转变(从用户定义的数据类型/操作到 CPU 指令集)是如何发生的,编译器、解释器、汇编器和链接器在这
Raspberry Pi 3 uses a Broadcom SoC with and ARMv8 A53 core .它还使用基于 Debian Jessie 的 32 位操作系统。根据 ARM 的
这个问题在这里已经有了答案: How to create a lightweight C code sandbox? (13 个答案) 关闭 9 年前。 我正在开发一个类似于 hackerrank.
下面的代码是否可以用来检查 CPU 是否支持 SSE3 指令集? 使用 IsProcessorFeaturePresent()该功能显然不适用于 Windows XP。 bool CheckSSE3(
我想编译一个包含大量 32 位静态库的程序,由于缺少 makefile,我无法将其重新编译为 64 位,但我应该编译一些库以获得一些静态库以与它们一起使用。 我要编译的库之一有一个 Makefile,
我知道 SSE 是 x87 浮点指令的替代方法,但 x87 FPU 是否仍在 Ivy-Bridge 或 Haswell 等现代 CPU 中实现? SSE 是否取代了 x87 指令集? 最佳答案 x87
我知道这个问题已经有一些答案,但我似乎不明白为什么我一直收到这个错误。 下面是解释:我有 64 位机器,其中安装了 Windows 7 x64。我在 Windows 上的 GCC (CodeBlock
我们有一个要用 AVX2 编译的翻译单元(只有那个):它在文件的第一行预先告诉 GCC: #pragma GCC target "arch=core-avx2,tune=core-avx2" 这曾经适
我想使用 mfoc library使用我的 Galaxy Nexus 手机,但 NFC Android API 中缺少某些方法。所以我想实现这些方法并构建我自己的 ROM。 使用 NFC pn512
我希望以快速高效的方式用 C 语言编写 Morton Z 顺序编码和解码的两个函数,即。 uint64_t morton_encode(uint32_t xindex, uint32_t yindex
我在 Visual C++ 2010 中使用 OpenCV 中的 BRIEF 描述符来匹配两个图像中的点。 在the paper关于 BRIEF-descriptor 的内容是可以加快速度: "The
我正在尝试制作一个对 2 个 CGVectors 求和的函数。 这是我的尝试: 包括: @import GLKit; @import Foundations; // Defenition of
所以,这就是我要完成的工作。在我的 C++ 项目中,必须使用 Microsoft Visual Studio 2015 或更高版本编译,我需要一些代码具有不同的版本,具体取决于用户 CPU 中可用的最
我是一名优秀的程序员,十分优秀!