- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想确保gcc知道:
template<typename T, typename T2>
void f(const T* __restrict__ __attribute__((aligned(32))) x,
T2* __restrict__ __attribute__((aligned(32))) out) {}
int square(const float* __restrict__ __attribute__((aligned(32))) x,
const int size,
float* __restrict__ __attribute__((aligned(32))) out0,
float* __restrict__ __attribute__((aligned(32))) out1,
float* __restrict__ __attribute__((aligned(32))) out2,
float* __restrict__ __attribute__((aligned(32))) out3,
float* __restrict__ __attribute__((aligned(32))) out4) {
for (int i = 0; i < size; ++i) {
out0[i] = x[i];
out1[i] = x[i] * x[i];
out2[i] = x[i] * x[i] * x[i];
out3[i] = x[i] * x[i] * x[i] * x[i];
out4[i] = x[i] * x[i] * x[i] * x[i] * x[i];
}
}
.L3:
vmovups ymm1, YMMWORD PTR [rbx+rax]
vmulps ymm0, ymm1, ymm1
vmovups YMMWORD PTR [r14+rax], ymm0
vmulps ymm0, ymm1, ymm0
vmovups YMMWORD PTR [r15+rax], ymm0
vmulps ymm0, ymm1, ymm0
vmovups YMMWORD PTR [r12+rax], ymm0
vmulps ymm0, ymm1, ymm0
vmovups YMMWORD PTR [rbp+0+rax], ymm0
add rax, 32
cmp rax, rdx
jne .L3
and r13d, -8
vzeroupper
.L3:
vmovups xmm2, XMMWORD PTR [rbx+rax]
vinsertf128 ymm1, ymm2, XMMWORD PTR [rbx+16+rax], 0x1
vmulps ymm0, ymm1, ymm1
vmovups XMMWORD PTR [r14+rax], xmm0
vextractf128 XMMWORD PTR [r14+16+rax], ymm0, 0x1
vmulps ymm0, ymm1, ymm0
vmovups XMMWORD PTR [r13+0+rax], xmm0
vextractf128 XMMWORD PTR [r13+16+rax], ymm0, 0x1
vmulps ymm0, ymm1, ymm0
vmovups XMMWORD PTR [r12+rax], xmm0
vextractf128 XMMWORD PTR [r12+16+rax], ymm0, 0x1
vmulps ymm0, ymm1, ymm0
vmovups XMMWORD PTR [rbp+0+rax], xmm0
vextractf128 XMMWORD PTR [rbp+16+rax], ymm0, 0x1
add rax, 32
cmp rax, rdx
jne .L3
and r15d, -8
vzeroupper
最佳答案
不,使用float *__attribute__((aligned(32))) x
意味着指针本身存储在对齐的内存中,而不是指向对齐的内存。1
有一种方法可以执行此操作,但是它仅对gcc有用,对clang或ICC无效。
有关适用于所有GNU C兼容编译器的__builtin_assume_aligned
,请参见How to tell GCC that a pointer argument is always double-word-aligned?;有关适用于GCC的__attribute__((aligned(32)))
的更多详细信息,请参见How can I apply __attribute__(( aligned(32))) to an int *?。
我使用__restrict
而不是__restrict__
,因为C99 restrict
的C++扩展名可移植到所有主流x86 C++编译器(包括MSVC)中。
typedef float aligned32_float __attribute__((aligned(32)));
void prod(const aligned32_float * __restrict x,
const aligned32_float * __restrict y,
int size,
aligned32_float* __restrict out0)
{
size &= -16ULL;
#if 0 // this works for clang, ICC, and GCC
x = (const float*)__builtin_assume_aligned(x, 32); // have to cast the result in C++
y = (const float*)__builtin_assume_aligned(y, 32);
out0 = (float*)__builtin_assume_aligned(out0, 32);
#endif
for (int i = 0; i < size; ++i) {
out0[i] = x[i] * y[i]; // auto-vectorized with a memory operand for mulps
// note clang using two separate movups loads
// instead of a memory operand for mulps
}
}
movaps
/
vmovaps
代替
ups
。 (与MSVC和ICC不同,它们从不使用
movaps
进行加载/存储,对于在Core2 / K10或更旧版本上运行的任何内容都缺少优化)。正如您所注意到的,它是将
-mavx256-split-unaligned-load
/
store
效果应用于除Haswell(
Why doesn't gcc resolve _mm256_loadu_pd as single vmovupd?)。之外的其他调音,这是您的语法无效的另一个线索。
vmovups
时不会出现性能问题;当地址在运行时对齐时,它在所有支持AVX的CPU上的性能与
vmovaps
相同。因此,在实践中,您的
-march=haswell
输出没有真正的问题。只有Nehalem和Bulldozer之前的较旧的CPU始终将
movups
解码为多个uops。
mulps
的内存操作数中。
out0[i] = x[i] * y[i]
,其中加载结果仅需要一次。 或
out0[i] *= x[i]
。知道对齐方式后,就可以启用
movaps
/
mulps xmm0, [rsi]
,否则为2x
movups
+
mulps
。您甚至可以在ICC或MSVC之类的编译器上检查此优化,即使它们知道有对齐保证也使用
movups
,但是当他们可以将负载折叠到ALU操作中时,仍会生成需要对齐的代码。
__builtin_assume_aligned
是执行的唯一真正可移植的方式(对于GNU C编译器)。您可以像将指针传递给
struct aligned_floats { alignas(32) float f[8]; };
一样进行破解,但这使用起来很麻烦,并且除非您实际上通过该类型的对象访问内存,否则编译器将无法假定对齐。 (例如,将指向该指针的指针转换回
float *
I try to use one read and lots of write to saturate the cpu ports for writing.
c[i] = a[i]+b[i]
或STREAM triad这样的2倍负载+ 1倍存储内存访问模式将最接近
maxing out total L1d cache load+store bandwidth。在SnB / IvB上,每个加载/存储256位 vector 需要2个周期,因此在加载的第二个周期内,存储地址oups需要时间在端口2或3上使用AGU。在Haswell及更高版本(256位宽的加载/存储端口)上,存储需要使用非索引寻址模式,以便它们可以在端口7上使用简单寻址模式存储AGU。
and rsp,-32
,因为它假定RSP已对齐。 (它实际上并没有溢出任何YMM规则,因此无论如何它都应该对此进行了优化,但是gcc在使用局部对齐或自动矢量化创建的对象时已经存在此错过优化的错误一段时间了。)
<source>:4:6: note: The ABI for passing parameters with 32-byte alignment has changed in GCC 4.6
关于c++ - 结合__restrict__和__attribute __((aligned(32))),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54189780/
设置.py CELERY_BROKER_URL = 'redis://localhost:6379' CELERY_RESULT_BACKEND = 'redis://localhost:6379'
在 thymeleaf 中, [__${roleStat.index}__] 部分在做什么? 我知道这是数组索引,但是 __ 是做什么用的? 最佳答案 This doc说(第 26 页): Prepr
我正在使用以下时间选择器,它给出了 --:-- 有什么方法可以转换默认值 --:--至 __:__来自时间域? 最佳答案 在 Chromium 中,您可以使用 ::-webkit-datetime-
随着我正在从事的项目变得越来越大,我已经厌倦了编写全面的日志消息,需要找出问题所在和出处。 因此,如果我可以将该信息自动合并到消息中,将非常有用。对于C++,我们有方便的__FILE__,__LINE
我有以下代码: #ifdef __SYM_TRACE__ #define SYM_TRACE( L, F ) { SETTRACE_LEVEL(L); tracefunc F; } #define
假设我创建了一个这样的自定义异常类: class MyError(Exception): def __init__(self, msg): pass raise MyError
让我们假设以下代码: char* c = __FILE__; c是否存在于堆栈或堆中? (作为后续措施-我可以将c传递给另一个线程进行处理,还是需要在其他地方存储数据?)。 谢谢你。 最佳答案 c是指
我的 Activity 中有一个 EditText,用户必须以我想要的格式在其中输入日期,例如 ____/__/__。有没有办法像某些编程语言的掩码文本框一样在Android的EditText中显示这
我试图区分 while 循环的不同编写方式。 我专门为一个扑克游戏写这篇文章,我在其中区分不同的手牌类型。在编写我的 is_pair 函数时,我首先说 pair = False。我发现继续循环的唯一方
是否有遵循 ____ 模式的方法?并作为别名工作,而不是 __send__ ? 最佳答案 很容易找到与您的模式匹配的方法名称列表: ObjectSpace.each_object(Module).fl
我正在尝试创建一个循环遍历列表的脚本。 我需要查看能力标识符的有限列表 (400)(例如 124、129 等 - 普通整数) 然后我有一本字典,记录每个用户拥有的能力。键是用户名,每个键的值是整数列表
这个问题已经有答案了: __proto__ VS. prototype in JavaScript (34 个回答) 已关闭 8 年前。 我没有正确地理解这一点。我看到了一个与之相关的问题,但无法从中
我正在尝试使用 chartjs 制作图表用于显示民意调查投票的所有统计数据。这是针对有 12 个月的特定年份。 例如, 你是程序员吗? 是 没有 我想在图表中显示 - 用户给一年中的 12 个月投了多
几个月前我刚开始学习 Python,我正在尝试了解不同 __get*__ 方法之间的区别: __get__ __getattr__ __getattribute__ __getitem___ 以及它们
我有一个充满ActiveX控件的工作表。我知道他们在工作表上有错误,所以这是我实现的用于重置控件并保持其行为受控的功能。 问题在于,错误处理程序无法捕获由于尝试访问ListBox的auto-size属
我正在将可以在Linux上完美运行的代码移植到Windows visual c++。 我在Linux中有以下代码: struct exif_desc { uint16_t tag;
RegEx 一直让我感到困惑。 我有这样一个字符串: IDE\DiskDJ205GA20_____________________________A3VS____\5&1003ca0&0&0.0.
这个问题已经有答案了: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’ (8 个回答) C Forma
我试图在 Intellij IDEA 中查看一个大文件,但遇到错误:“文件太大:30.1 MB,显示第一个 2.56 MB 的只读预览”。 我看过这个问题的一些以前的答案,包括: IntelliJ c
我正在尝试学习用于跨平台 GUI 开发的 wxwidgets,但是我遇到了一个问题。 当尝试使用 mingW32 构建 wxwidgets 时,我遇到了错误。我安装了带有代码块 16.1 的 minG
我是一名优秀的程序员,十分优秀!