Tag: alignment

使用-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__行以生成未对齐的循环体。

为什么_mm256_load_pd编译为MOVUPD而不是MOVAPD?

为什么以下代码会产生未对齐的AVX指令(MOVUPD而不是MOVAPD)? 我在Visual Studio 2015上编译了这个。如何告诉编译器我的数据确实是对齐的? const size_t ALIGN_SIZE = 64; const size_t ARRAY_SIZE = 1024; double __declspec(align(ALIGN_SIZE)) a[ARRAY_SIZE]; double __declspec(align(ALIGN_SIZE)) b[ARRAY_SIZE]; //Calculate the dotproduct __m256d ymm0 = _mm256_set1_pd(0.0); for (int i = 0; i < ARRAY_SIZE; i += 8) { __m256d ymm1 = _mm256_load_pd(a + i); __m256d ymm2 = _mm256_load_pd(b + i); __m256d ymm3 = _mm256_mul_pd(ymm1, […]

结构填充是否可以由用户代码安全使用?

假设我有一个如下所示的结构: struct Struct { char Char; int Int; }; 和sizeof( int )大于1并且编译器为Char成员变量添加填充 – 编译器生成的代码是否允许更改填充字节的值? 我的意思是,如果我使用指针运算并将一些数据写入Char成员变量周围的填充字节,然后执行variable.Char =赋值,编译器生成的代码是否也可能会覆盖某些填充字节?

位字段及其对齐如何在C编程中起作用?

我需要你帮助理解位域在C编程中的工作原理。 我已经声明了这个结构: struct message { unsigned char first_char : 6; unsigned char second_char : 6; unsigned char third_char : 6; unsigned char fourth_char : 6; unsigned char fifth_char : 6; unsigned char sixth_char : 6; unsigned char seventh_char : 6; unsigned char eigth_char : 6; }__packed message; 我使用sizeof(message)将结构的大小保存为整数。 我认为大小的值将是6,因为6 * 8 = 48位,这是6个字节,但它的大小值为8个字节。 任何人都可以向我解释为什么,以及比特字段和它们的比对是如何工作的? 编辑 […]

malloc返回的内存地址是否总是可以通过指向另一种类型的指针互换?

char arr[512] = {0}; int *ptr = (int *)arr; // WRONG // A bus error can be caused by unaligned memory access printf(“%d\n”, *ptr); 另一方面: malloc为您提供的块保证对齐,以便它可以保存任何类型的数据。 char *arr= malloc(512); int *ptr = (int *)arr; // OK, arr is properly aligned for ptr memset(arr, 0, 512); printf(“%d\n”, *ptr); 这个假设是正确的还是我错过了什么?

字对齐加载比x64处理器上的未对齐加载更快吗?

在x86 / 64(Intel / AMD 64位)处理器上,在字边界上对齐的变量是否比未对齐的加载操作更快? 我的一位同事辩称,未对齐的载荷很慢,应该避免。 他引用了项目填充到结构中的单词边界,作为未对齐加载缓慢的证据。 例: struct A { char a; uint64_t b; }; 结构A通常大小为16个字节。 另一方面, Snappy压缩器的文档指出Snappy认为“未对齐的32位和64位负载和存储很便宜”。 根据源代码,英特尔32和64位处理器也是如此。 那么:这里的真相是什么? 如果和未对齐的负载有多少? 在哪种情况下?

如何使用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编译器选项。

C结构大小对齐

我希望C结构的大小是16个字节的倍数(16B / 32B / 48B / ..)。 它到达的大小无关紧要,它只需要16B的倍数。 我怎么能强制编译器这样做? 谢谢。

C类结构中自动字段重新排序的方法

有没有办法在C-like结构中执行自动字段重新排序 ? 我的意思是使用语言function(如C和C ++的预处理器和C ++的模板/类型特征/等),这使得可以执行以下宏(类似Boost.Fusion的样式来适应结构): REARRANGE(StructureName, (int8_t)(FieldName1), (int32_t)(FieldName2), (int16_t)(FieldName3), (int32_t)(FieldName4)); // is equivalent to (without loss of generality): struct StructureName { int32_t FieldName2; int32_t FieldName4; int16_t FieldName3; int8_t FieldName1; }; 当然,方法应考虑alignof值(以及sizeof ),如果可能,还应考虑#pragma pack current value。 我知道结果的可移植性差,但仅供本地使用。 将字段名称与各个类型一起保存是强制性的。 目的是减少总体结构尺寸。

如何在C中分配和释放对齐的内存

如何分配与C中特定边界对齐的内存(例如,缓存行边界)? 我正在寻找malloc / free类似的实现,理想情况下尽可能便携 – 至少在32位和64位架构之间。 编辑添加:换句话说,我正在寻找一些表现得像(现在过时的?) memalign函数的东西,它可以免费使用。