- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个想法,用于编写特定类型的数值算法的代码风格,您可以纯粹以与数据布局无关的方式编写算法。
即所有函数都接受(一个或多个)标量参数,并(通过指针)返回一个或多个标量返回值。因此,举例来说,如果您有一个采用 3d 浮点 vector 的函数,而不是采用具有三个成员的结构体或 float[3] xyz,您采用 float x、float y、float z。
这个想法是,您可以更改输入和输出数据的布局,即您可以使用数组结构与结构数据布局数组、用于缓存效率的平铺布局、SIMD 与多核粒度等。 .无需为所有数据布局组合重写所有代码。
该策略有一些明显的缺点:
...但是如果您的数组很短,那么这些是可以接受的,并且它可以让您不必多次重写代码以使其更快。
但特别是,我担心编译器可能无法接受像 x+=a; 这样的东西。 y+=b; z+=c; w+=d 并将其自动向量化为单个 SIMD vector 加法,如果您想在调用堆栈的底部执行 SIMD,而不是在内联函数堆栈的顶部执行 SIMD。
clang 和/或 gcc 是否能够在 C 和/或 C++ 代码中“重新滚动”手动展开的循环(可能在内联函数之后)并生成矢量化机器代码?
最佳答案
我编写了一些代码来对我的想法进行简单的测试:
// Compile using gcc -O4 main.c && objdump -d a.out
void add4(float x0, float x1, float x2, float x3,
float y0, float y1, float y2, float y3,
float* out0, float* out1, float* out2, float* out3) {
// Non-inlined version of this uses xmm registers and four separate
// SIMD operations
*out0 = x0 + y0;
*out1 = x1 + y1;
*out2 = x2 + y2;
*out3 = x3 + y3;
}
void sub4(float x0, float x1, float x2, float x3,
float y0, float y1, float y2, float y3,
float* out0, float* out1, float* out2, float* out3) {
*out0 = x0 - y0;
*out1 = x1 - y1;
*out2 = x2 - y2;
*out3 = x3 - y3;
}
void add4_then_sub4(float x0, float x1, float x2, float x3,
float y0, float y1, float y2, float y3,
float z0, float z1, float z2, float z3,
float* out0, float* out1, float* out2, float* out3) {
// In non-inlined version of this, add4 and sub4 get inlined.
// xmm regiesters get re-used for the add and subtract,
// but there is still no 4-way SIMD
float temp0,temp1,temp2,temp3;
// temp= x + y
add4(x0,x1,x2,x3,
y0,y1,y2,y3,
&temp0,&temp1,&temp2,&temp3);
// out = temp - z
sub4(temp0,temp1,temp2,temp3,
z0,z1,z2,z3,
out0,out1,out2,out3);
}
void add4_then_sub4_arrays(const float x[4],
const float y[4],
const float z[4],
float out[4])
{
// This is a stand-in for the main function below, but since the arrays are aguments,
// they can't be optimized out of the non-inlined version of this function.
// THIS version DOES compile into (I think) a bunch of non-aligned moves,
// and a single vectorized add a single vectorized subtract
add4_then_sub4(x[0],x[1],x[2],x[3],
y[0],y[1],y[2],y[3],
z[0],z[1],z[2],z[3],
&out[0],&out[1],&out[2],&out[3]
);
}
int main(int argc, char **argv)
{
}
考虑为 add4_then_sub4_arrays 生成的程序集:
0000000000400600 <add4_then_sub4_arrays>:
400600: 0f 57 c0 xorps %xmm0,%xmm0
400603: 0f 57 c9 xorps %xmm1,%xmm1
400606: 0f 12 06 movlps (%rsi),%xmm0
400609: 0f 12 0f movlps (%rdi),%xmm1
40060c: 0f 16 46 08 movhps 0x8(%rsi),%xmm0
400610: 0f 16 4f 08 movhps 0x8(%rdi),%xmm1
400614: 0f 58 c1 addps %xmm1,%xmm0
400617: 0f 57 c9 xorps %xmm1,%xmm1
40061a: 0f 12 0a movlps (%rdx),%xmm1
40061d: 0f 16 4a 08 movhps 0x8(%rdx),%xmm1
400621: 0f 5c c1 subps %xmm1,%xmm0
400624: 0f 13 01 movlps %xmm0,(%rcx)
400627: 0f 17 41 08 movhps %xmm0,0x8(%rcx)
40062b: c3 retq
40062c: 0f 1f 40 00 nopl 0x0(%rax)
数组没有对齐,因此移动操作比理想情况要多得多,我不确定异或在那里做什么,但确实有一个 4 路加法和一个 4 路减法根据需要。
所以答案是 gcc 至少有一些能力将标量浮点运算打包回 SIMD 运算。
更新:使用 gcc-4.8 -O3 -march=native main.c && objdump -d a.out
更紧凑的代码:
0000000000400600 <add4_then_sub4_arrays>:
400600: c5 f8 10 0e vmovups (%rsi),%xmm1
400604: c5 f8 10 07 vmovups (%rdi),%xmm0
400608: c5 f0 58 c0 vaddps %xmm0,%xmm1,%xmm0
40060c: c5 f8 10 0a vmovups (%rdx),%xmm1
400610: c5 f8 5c c1 vsubps %xmm1,%xmm0,%xmm0
400614: c5 f8 11 01 vmovups %xmm0,(%rcx)
400618: c3 retq
400619: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
并使用clang-4.0 -O3 -march=native main.c && llvm-objdump -d a.out
:
add4_then_sub4_arrays:
4005e0: c5 f8 10 07 vmovups (%rdi), %xmm0
4005e4: c5 f8 58 06 vaddps (%rsi), %xmm0, %xmm0
4005e8: c5 f8 5c 02 vsubps (%rdx), %xmm0, %xmm0
4005ec: c5 f8 11 01 vmovups %xmm0, (%rcx)
4005f0: c3 ret
4005f1: 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
关于c++ - Clang 或 GCC 是否能够自动矢量化手动展开的循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40995032/
我是 python 的新手。我试图找到我的文本的频率分布。这是代码, import nltk nltk.download() import os os.getcwd() text_file=open(
我对安卓 fragment 感到困惑。我知道内存 fragment 但无法理解什么是 android fragment 问题。虽然我发现很多定义,比如 Android fragmentation re
尝试对 WordPress 进行 dockerise 我发现了这个场景: 2个数据卷容器,一个用于数据库(bbdd),另一个用于wordpress文件(wordpress): sudo docker
这个问题已经有答案了: From the server is there a way to know that my page is being loaded in an Iframe (1 个回答)
我正在玩小型服务器,试图对运行在其上的服务进行docker化。为简化起见,假设我必须主要处理:Wordpress和另一项服务。 在Docker集线器上有许多用于Wordpress的图像,但是它们似乎都
我想要发生的是,当帐户成功创建后,提交的表单应该消失,并且应该出现一条消息(取决于注册的状态)。 如果成功,他们应该会看到一个简单的“谢谢。请检查您的电子邮件。” 如果不是,那么他们应该会看到一条适当
就是这样,我需要为客户添加一个唯一标识符。通过 strip 元数据。这就是我现在完全构建它的方式,但是我只有最后一部分告诉我用户购买了哪个包。 我试着看这里: Plans to stripe 代码在这
我有一个类将执行一些复杂的操作,涉及像这样的一些计算: public class ComplexAction { public void someAction(String parameter
这个问题已经有答案了: maven add a local classes directory to module's classpath (1 个回答) 已关闭10 年前。 我有一些不应更改的旧 E
我使用 fragment 已经有一段时间了,但我经常遇到一个让我烦恼的问题。 fragment 有时会相互吸引。现在,我设法为此隔离了一个用例,它是这样的: Add fragment A(也使用 ad
我的 html 中有一个 ol 列表,上面有行条纹。看起来行条纹是从数字后面开始的。有没有办法让行条纹从数字开始? 我已经包含了正在发生的事情的片段 h4:nth-child(even) {
如何仅使用 css 将附加图像 html 化? 如果用纯 css 做不到,那我怎么能至少用一个图像来做 最佳答案 这不是真正的问题,而是您希望我们为您编写代码。我建议您搜索“css breadcrum
以下是 Joshua 的 Effective Java 的摘录: If you do synchronize your class internally, you can use various te
在这里工作时,我们有一个框向业务合作伙伴提供 XML 提要。对我们的提要的请求是通过指定查询字符串参数和值来定制的。其中一些参数是必需的,但很多不是。 例如,我们要求所有请求都指定一个 GUID 来标
我有 3 个缓冲区,其中包含在 32 位处理器上运行的 R、G、B 位数据。 我需要按以下方式组合三个字节: R[0] = 0b r1r2r3r4r5r6r7r8 G[0] = 0b g1g2g3g4
我最近发现了关于如何使用 History.js、jQuery 和 ScrollTo 通过 HTML5 History API 对网站进行 Ajax 化的要点:https://github.com/br
我们有一个 Spring Boot 应用程序,由于集成需要,它变得越来越复杂——比如在你这样做之后发送一封电子邮件,或者在你之后广播一条 jms 消息等等。在寻找一些更高级别的抽象时,我遇到了 apa
我正在尝试首次实施Google Pay。我面临如何指定gateway和gatewayMarchantId的挑战。 我所拥有的是google console帐户,不知道在哪里可以找到此信息。 priva
昨天下午 3 点左右,我为两个想要从一个 Azure 帐户转移到另一个帐户的网站设置了 awverify 记录。到当天结束时,Azure 仍然不允许我添加域,所以我赌了一把,将域和 www 子域重新指
我正在使用terms facet在elasticsearch服务器中获取顶级terms。现在,我的标签"indian-government"不被视为一个标签。将其视为"indian" "governm
我是一名优秀的程序员,十分优秀!