Tag: memory alignment

MPI派生的数据类型适用于浮点数,但不适用于双精度数。 这是对齐问题吗?

我有一个与C结构相关的奇怪问题,它是在MPI派生数据类型的帮助下进行通信的。 以下示例有效; 它只是发送一个由一个integer加上4个float值组成的消息。 Minmum工作示例: #include #include int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int i, rank, tag = 1; MPI_Status status; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // Array of doubles plus element count typedef struct { int row; float elements[4]; } My_array; // Derived datatype for an array of doubles plus element count MPI_Datatype MY_ARRAY_TYPE; const int […]

使用-falign-loops选项时这是一个GCC错误吗?

我正在使用此选项来优化嵌入式架构中的for循环( 此处 )。 但是,我注意到当对齐需要添加多个nop指令时,编译器会生成一个nop后跟as-many-as-required零( 0000 )。 我怀疑它是我们编译器中的一个错误,但有人可以确认它不是GCC中的错误吗? 这是一段代码: __asm__ volatile(“nop”); __asm__ volatile(“nop”); for (j0=0; j0<N; j0+=4) { c[j0+ 0] = a[j0+ 0] + b[j0+ 0]; c[j0+ 1] = a[j0+ 1] + b[j0+ 1]; c[j0+ 2] = a[j0+ 2] + b[j0+ 2]; c[j0+ 3] = a[j0+ 3] + b[j0+ 3]; } 使用-falign-loops=8 (或与您的体系结构相关的任何数量,超过所需的最小比对)进行编译。 您可以根据需要添加或删除__asm__行以生成未对齐的循环体。

C / C ++ Struct内存布局等效

考虑以下C结构和C ++结构声明: extern “C” { // if this matters typedef struct Rect1 { int x, y; int w, h; } Rect1; } struct Vector { int x; int y; } struct Rect2 { Vector pos; Vector size; } Rect1和Rect2对象的内存布局是否始终相同? 具体来说,我可以安全地从Rect2*到Rect1*并假设Rect2对象中的所有四个int值Rect2匹配到Rect1的四个int吗? 如果我将Rect2更改为非POD类型(例如通过添加构造函数)会有所不同吗?

是否需要“双”型的8字节对齐?

我理解字对齐,这使得cpu只需要在将整数读入寄存器时读取一次。 但是需要“双”的8字节对齐 (让我们假设32位系统)? 有什么好处? 如果用于存储“double”的空间只是4字节对齐,会发生什么?

__memcpy_sse2_unaligned – 这是什么意思?

在处理我的编译器时,我遇到了这个错误: Program received signal SIGSEGV, Segmentation fault. __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33 我如何获得此处出现问题的详细信息? 我从回溯中知道它是一个记忆线导致它,但我如何看待内存是如何对齐的? 我怎么知道它应该如何对齐? 该项目是一个带有LLVM后端的编译器,使用Zend / PHP运行时和OCaml垃圾收集器,因此有很多问题可能出错。 我怀疑这条线是问题的一部分: zend_string *str = (zend_string *)caml_alloc(ZEND_MM_ALIGNED_SIZE(_STR_HEADER_SIZE + len + 1), 0); 其中caml_alloc是Zend源代码中的pemalloc 。 在执行10,000个字符串连接时会发生段错误。 这是valgrind的输出: ==7501== Invalid read of size 8 ==7501== at 0x4C2F790: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7501== by 0x4D7E58: subsetphp_concat_function (bindings.c:160) ==7501== by 0x4D7F52: foo (llvm_test.s:21) ==7501== […]

GCC上#pragma pack(push,n)/ #pragma pack(pop)和__attribute __((__ packed __,aligned(n)))之间有什么区别?

特别是在GCC上(即用GCC编译),以下两种方式有什么区别? struct foo1 { char a; int b; } __attribute__((__packed__, aligned(n) )); 和: #pragma pack(push, n) struct foo2 { char a; int b; }; #pragma pack(pop) 它们看起来表现不同 : foo1 f1; foo2 f2; int& i1 = f1.b; // ok int& i2 = f2.b; // cannot bind packed field ‘f2.foo2::b’ to ‘int&’ 为什么一个错误而另一个错误呢? 内存布局至少相同吗?

检测目标CPU上的对齐内存要求

我目前正在尝试构建一个代码,该代码可用于各种机器,从手持式口袋和传感器到数据中心的大型服务器。 这些体系结构之间的(许多)差异之一是对齐内存访问的要求。 “标准”x86 CPU不需要对齐的内存访问,但是如果不遵守规则,许多其他CPU需要它并产生exception。 到目前为止,我一直在使用packed属性(或pragma)强制编译器对已知存在风险的特定数据访问保持谨慎。 它工作正常。 问题是,编译器非常谨慎,以至于在此过程中会丢失大量性能。 由于性能很重要,我们最好重写代码的某些部分以专门处理严格对齐的cpus。 另一方面,这样的代码在cpus上会更慢,它支持未对齐的内存访问(例如x86),因此我们只想在需要严格对齐内存访问的cpus上使用它。 现在的问题是:如何在编译时检测目标架构是否需要严格对齐的内存访问? (或反过来)

在文本段中创建具有给定大小的C函数

我正在编写一个嵌入式powerpc 32系统,它带有一个32 KB的8路组关联L2指令缓存。 为了避免高速缓存抖动,我们以一种方式对齐函数,使得以高频率调用的一组函数的文本(想想中断代码)最终在单独的高速缓存集中。 我们通过根据需要插入虚函数来实现这一点,例如 void high_freq1(void) { … } void dummy(void) { __asm__(/* Silly opcodes to fill ~100 to ~1000 bytes of text segment */); } void high_freq2(void) { … } 这让我感到丑陋和不理想。 我想做的是 完全避免使用__asm__并使用纯C89(可能是C99) 找到一种方法来创建GCC优化器不接触的所需的dummy()间隔 dummy() spacer的大小应该可以配置为4个字节的倍数。 典型的间隔物为260至1000个字节。 对于总共500个函数中的一组约50个函数应该是可行的 我也愿意探索以一种方式放置一组选定函数的全新技术,这样它们就不会映射到相同的缓存行。 链接器脚本可以这样做吗?

如何使用GCC对齐C for-loop体?

在我们的嵌入式架构中,我们有一个64位IAB(指令对齐缓冲器)。 为了优化获取序列,需要循环体开始与8字节边界对齐。 使用.balign指令很容易在汇编中实现这一点,但我找不到一个会暗示C编译器对齐代码的语法。 尝试在带有.balign指令的内联汇编的for循环之前不起作用,因为它对齐for循环prolog(设置)而不是循环体本身。 在asm()行位于循环内部的情况下,将nop -s添加到循环体中,这需要花费宝贵的周期。 编辑1:假设代码: __asm__ volatile(“nop”); __asm__ volatile(“nop”); for (j0=0; j0<N; j0+=4) { c[j0+ 0] = a[j0+ 0] + b[j0+ 0]; c[j0+ 1] = a[j0+ 1] + b[j0+ 1]; c[j0+ 2] = a[j0+ 2] + b[j0+ 2]; c[j0+ 3] = a[j0+ 3] + b[j0+ 3]; } 我希望第一个c=a+b与8字节地址对齐。 我可以在初步编译后添加类似上面的nop -s,但这是一个特殊的解决方案,它会破坏第一个代码更改。 编辑2:感谢@R ..,解决方案是使用-falign-loops=8编译器选项。

这个尺寸对齐是如何工作的

关于提供的评论,我无法理解以下代码。 这段代码做了什么,以及8-aligned的等效代码是什么? /* segment size must be 4-aligned */ attr->options.ssize &= ~3; 这里, ssize是unsigned int类型。