- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
只有当循环在 AVX 机器(Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz)上完全矢量化时,我才会在循环中遇到段错误。
使用 gcc -c -march=native MyClass.cpp -O3 -ftree-vectorizer-verbose=6 编译
我正在尝试对齐数组,以避免来自 -ftree-vectorizer-verbose=6 的这些消息:
MyClass.cpp:352: note: dependence distance modulo vf == 0 between this_7(D)->x[i_101] and this_7(D)->x[i_101]
MyClass.cpp:352: note: vect_model_load_cost: unaligned supported by hardware.
MyClass.cpp:352: note: vect_get_data_access_cost: inside_cost = 2, outside_cost = 0.
MyClass.cpp:352: note: vect_model_store_cost: unaligned supported by hardware.
MyClass.cpp:352: note: vect_get_data_access_cost: inside_cost = 2, outside_cost = 0.
MyClass.cpp:352: note: Alignment of access forced using peeling.
MyClass.cpp:352: note: vect_model_load_cost: aligned.
MyClass.cpp:352: note: vect_model_load_cost: inside_cost = 1, outside_cost = 0 .
MyClass.cpp:352: note: vect_model_simple_cost: inside_cost = 1, outside_cost = 1 .
MyClass.cpp:352: note: vect_model_store_cost: aligned.
MyClass.cpp:352: note: vect_model_store_cost: inside_cost = 1, outside_cost = 0 .
MyClass.cpp:352: note: cost model: prologue peel iters set to vf/2.
MyClass.cpp:352: note: cost model: epilogue peel iters set to vf/2 because peeling for alignment is unknown .
我想看到(也确实看到了)的是:
MyClass.cpp:352: note: dependence distance modulo vf == 0 between this_7(D)->x[i_101] and this_7(D)->x[i_101]
MyClass.cpp:352: note: vect_model_load_cost: aligned.
MyClass.cpp:352: note: vect_get_data_access_cost: inside_cost = 1, outside_cost = 0.
MyClass.cpp:352: note: vect_model_store_cost: aligned.
MyClass.cpp:352: note: vect_get_data_access_cost: inside_cost = 2, outside_cost = 0.
MyClass.cpp:352: note: vect_model_load_cost: aligned.
MyClass.cpp:352: note: vect_model_load_cost: inside_cost = 1, outside_cost = 0 .
MyClass.cpp:352: note: vect_model_simple_cost: inside_cost = 1, outside_cost = 1 .
MyClass.cpp:352: note: vect_model_store_cost: aligned.
MyClass.cpp:352: note: vect_model_store_cost: inside_cost = 1, outside_cost = 0 .
现在,我无论如何都不是 C/C++/汇编大师,但是当我遇到段错误时,我假设我的代码中有一些指针/数组/其他错误,并且完全矢量化的循环只是暴露了这个.但是在学习了两天的汇编程序之后,我无法找到它。所以我在这里。
代码看起来像这样(希望我包括了所有相关的东西——我不能在这里完整地分享实际的 .cpp):
class MyClass {
private:
static const long maxElems = 1024;
static const double otherVar = 0.9;
double x[maxElems] __attribute__ ((aligned (32))); <-- gcc reports fully vectorized
//double x[maxElems]; <-- leads to unaligned peeling
public:
void myFunc() {
// Always works
for (int i=0; i<maxElems; ++i) printf("Test: %d %.4e\n", i, x[i]);
// Seg fault if fully vectorized (no peeling)
for (int i=0; i<maxElems; ++i) {
x[i] = x[i] - 42;
}
// Works if no seg fault earlier
for (int i=0; i<maxElems; ++i) printf("Test: %d %.4e\n", i, x[i]);
}
}
当它完全矢量化时,我看到(使用 -Wa,-alh 标志来查看汇编程序):
989 00
990 0b56 488B4424 movq 40(%rsp), %rax
990 28
991 0b5b C5FD280D vmovapd .LC8(%rip), %ymm1
991 00000000
992 .p2align 4,,10
993 0b63 0F1F4400 .p2align 3
993 00
994 .L153:
995 0b68 C5FD2800 vmovapd (%rax), %ymm0
996 0b6c C5FD5CC1 vsubpd %ymm1, %ymm0, %ymm0
997 0b70 C5FD2900 vmovapd %ymm0, (%rax)
998 0b74 4883C020 addq $32, %rax
999 0b78 4C39E0 cmpq %r12, %rax
1000 0b7b 75EB jne .L153
同样,关于“不了解汇编器”的常见警告,但我确实花了相当多的时间打印指针和检查汇编器以说服自己这个循环在数组的开始和结束处开始和结束。但是当我遇到段错误时,x 的起始地址不能被 32 整除。我认为这就是造成麻烦的原因。
是的,我知道我可以在堆上分配 x 并选择它最终对齐的位置。但是我在这里的部分实验是让 MyClass 的所有数据都固定大小(想想:缓存效率),所以我在堆上分配了 MyClass 的实例,在集合中指向它们的指针,并且 x 在 MyClass 内部.
align attribute 不是应该将 x 放在 32 字节边界上吗?编译器假设,然后 vmovapd 爆炸了,因为它不是,对吧?
关于对齐的 GCC 文档:https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
我是否必须以某种方式在堆上对齐 MyClass?我怎么做?我如何告诉 GCC 我这样做了,以便它像我想要的那样矢量化?
编辑:我已经解决了这个问题(部分归功于下面的评论和答案)。通过覆盖默认的 new
运算符,可以保证在堆上创建对象时对齐。当我这样做时,我没有遇到任何段错误,而且我的代码仍然按照我的意愿完美矢量化。我是怎么做到的:
static void* operator new(size_t size) throw (std::bad_alloc) {
void *alignedPointer;
int alignError = 0;
// Try to allocate the required amount of memory (using POSIX standard aligned allocation)
alignError = posix_memalign(&alignedPointer, VECTOR_ALIGN_BYTES, size);
// Throw/Report error if any
if (alignError) {
throw std::bad_alloc();
}
// Return a pointer to this aligned memory location
return alignedPointer;
}
static void operator delete(void* alignedPointer) {
// POSIX aligned memory allocation can be freed normally with free()
free(alignedPointer);
}
C++ 会在调用运算符之后/之前为您调用构造函数/析构函数。因此,对齐由类本身控制。如果您有不同的偏好,也可以使用其他对齐的内存分配器。我用的是 POSIX。
两个注意事项:如果有人用任意地址调用 placement new
,您仍然不会对齐。如果有人将您的类声明为他们类的成员,并且他们的类分配在堆上,则您可能未对齐。我已经检查了我的构造函数,如果检测到它会抛出错误。
最佳答案
__attribute__((aligned(32))
可能不会像我们认为的那样(错误?功能?)。
它基本上告诉编译器它可以假设这个东西是对齐的,但它可能不是。如果它在堆上,则需要使用 posix_memalign
或类似方法进行分配。
如果设置了 __attribute__((aligned(...))
但分配未对齐,GCC 实际上会得到指针算术错误。
s2->aligned_var = 0x199c030
&s2->aligned_var % 0x40 = 0x0
关于c++ - GCC __attribute__ 在 32 字节处对齐的 AVX 向量化代码中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26620862/
我有一个目前正在用 C 编写的应用程序,其中我在作为项目一部分的库中声明了几个 TLS 静态全局变量。 TLS 变量是使用 gcc 的 __thread 指令声明的。 我想知道我是否可以使用 .cto
如果 C++ 类构造函数只能通过其参数访问数据,那么它们是否可以并且应该声明为 __attribute__((pure))?在什么情况下它们应该被限定为 __attribute__((const))?
遵循 GCC __attribute__(packed) 将打包到字节边界,对齐用于此目的:-- u8 rx_buf[14] __attribute__((aligned(8))); struct
__attribute__((const)) 和 GNU C 中的 __attribute__((pure)) 有什么区别? __attribute__((const)) int f() {
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
我想利用 GCC 的可见性属性。 为此,在我的可执行文件中,我有一个函数,我希望它对任何插件都可见,这样它们就可以使用它来注册自己。因此,我在其上使用 __attribute__((visibilit
有时我会出于各种原因围绕 printf 风格的函数编写包装器,我真的很喜欢让 clang 告诉我格式说明符和实际参数之间的类型不匹配。考虑: #include #include static __
我对以下代码行有疑问: char buffer[256] __attribute__((aligned(4096))); 全局数组“缓冲区”的内容是字符串,我从标准输入中获取。我读过https://g
在gcc documentation它们提供有关整数如何对齐的信息。 打包整数可以做同样的事情吗? 例如,这在不会自动处理不正确对齐数据的系统上有效吗? typedef uint16_t __attr
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: GCC __attribute__((aligned(x)) explanation What is mea
__attribute__ 指令是否适用于一行中声明的所有成员? int a, b, c; 声明三个 int 变量。 int *a, b, c; 将变量“a”声明为指向 int 的指针,将 b 和 c
在使用 gcc __attribute__ 函数时,我注意到代码生成存在差异,具体取决于我放置属性的位置。在下面的示例中,我希望编译器不要优化我对 use() 的调用。 编译器:x86-64 gcc(
为什么gcc需要__attribute__((__malloc__))?难道不应该通过将 malloc (和类似的函数)声明为返回 restricted 指针来传达相同的信息 (void *restr
我得到了一段将 __attribute__((const)) 应用于某些函数的代码。现在,我宁愿在它可用时不删除它,但另一方面,我确实想要更便携,所以 - 我想说 #if some condition
我可能对 weak 理解有误: 我的情况: 具有一些弱回调的“物理层” 实现这些回调的“框架层”,并为应用层提供新的 WEAK 回调 主要 - 应用层。 phy.h #pragma once void
我知道从C编程语言的角度main() 是程序的入口点。 但从操作系统的角度来看,__start 位于 ctrt0 启动例程,它链接到一个程序中,该程序在调用程序的 main() 函数(如有错误请指正)
这几天一直让我抓狂。如果我将数组声明为 static,则无法让数组对齐 16。 非常感谢任何帮助。 修订版: #include #include #define MAX_INPUTS 250 in
我正在尝试在 android NDK 上进行开发。我实际上有一个带有模块的项目+子文件夹(编译为静态库)并与主项目文件(libs .a + main object .o --> 可执行文件)链接在一起
这个问题在这里已经有了答案: Is there a standard "never returns" attribute for C# functions? (10 个答案) 关闭 8 年前。 C#
__attribute__ ((__packed__)) 对嵌套结构有什么影响?例如: // C version struct __attribute__ ((__packed__)) { s
我是一名优秀的程序员,十分优秀!