Tag: gcc

将打包数据与对齐的内存访问相结合

我正在尝试执行一个理论上可行的内存优化,但我开始怀疑是arm-elf-gcc的能力。 请告诉我,我错了。 我有一个嵌入式系统,主内存非常少,电池支持的nvram数量更少。 我将校验和配置数据存储在nvram中,以便在启动时我可以validation校验和并继续先前的运行或在校验和无效时开始新的运行。 在运行期间,我在此配置数据中更新了各种大小的各种字段(并且可以使校验和无效,直到稍后重新计算)。 所有这些都在物理地址空间中运行 – 正常的sram映射在一个位置,nvram映射到另一个位置。 这是擦除 – 所有对nvram的访问必须以32位字进行; 不允许字节或半字访问(虽然它在主存中显然很好)。 因此,我可以a)将所有配置数据的工作副本存储在主存储器中,并在重新计算校验和时将其存储到nvram中或b)直接在nvram中使用它,但不知何故说服编译器所有结构都是打包和所有访问不仅必须是32位对齐 ,还必须是32 位宽 。 选项a)浪费宝贵的主存储器,我宁愿通过选项b)进行运行时权衡以保存它(尽管不是代码大小最终浪费的东西比我节省的数据大小更多)。 我希望__attribute__ ((packed, aligned(4)))或其中的一些变体可以在这里提供帮助,但到目前为止我所做的所有阅读和实验都让我失望了。 这是我正在处理的配置数据的玩具示例: #define __packed __attribute__ ((packed)) struct __packed Foo { uint64_t foo; struct FooFoo foofoo; } struct __packed Bar { uint32_t something; uint16_t somethingSmaller; uint8_t evenSmaller; } struct __packed PersistentData { struct Foo; struct Bar; /* […]

gcc -Wpadded不提供任何警告

我正在尝试使用gcc的-Wpadded选项来了解gcc是否可以帮助我找出结构是否填充。 这是以下代码。 #include struct my { char *name; int age; } my_details; int main() { struct my person1; return 0; } 我使用以下代码编写了代码。 gcc -Wpadded alignment_demo.c 。 它没有返回任何警告。 那么我的结构没有填充或者我错过了什么? 然而, man gcc显示它支持一个名为-Wpadded的选项。 请帮助 谢谢奇丹巴拉姆

为什么位域的类型会影响包含结构的大小?

首先,这是ISO C标准关于位域的内容,引用2011年ISO C标准的N1570草案,第6.7.2.1节: 位字段的类型应为_Bool , signed int , unsigned int或其他实现定义类型的限定或非限定版本。 它是实现定义的,是否允许primefaces类型。 … 位字段被解释为具有由指定位数组成的有符号或无符号整数类型。 如果将值0或1存储到_Bool类型的非零宽度位字段中,则位字段的值应等于存储的值; _Bool位字段具有_Bool的语义。 实现可以分配足够大的任何可寻址存储单元来保持位字段。 如果剩余足够的空间,则紧跟在结构中的另一个位字段之后的位字段将被打包到相同单元的相邻位中。 如果剩余的空间不足,则是否将不适合的位域放入下一个单元或重叠相邻单元是实现定义的。 单元内的位域分配顺序(高阶到低阶或低阶到高阶)是实现定义的。 未指定可寻址存储单元的对齐。 对于任何struct类型,类型的对齐方式至少是该类型的任何成员的最大对齐方式,并且任何类型的大小都是其对齐方式的倍数。 例如,如果结构包含(非位域) int成员,并且int需要4字节对齐,则结构本身需要4字节对齐或更多。 许多编译器允许除_Bool和int类型之外的整数类型的位字段。 对于至少一些编译器,包含位字段的struct的对齐至少是声明的位字段类型的对齐。 例如,对于x86_64上的gcc 4.7.2,给出: struct sb { _Bool bf:1; }; struct si { unsigned bf:1; }; gcc给struct sb一个大小和1个字节的对齐(这是_Bool的大小和对齐), struct si是一个大小和4个字节的对齐(这是int的大小和对齐)。 它对实现定义类型的位字段做了同样的事情; 位字段定义为long long bf:1; 强制封闭结构的8字节大小和对齐。 即使在两种情况下,位字段bf是宽度仅为1位的对象,也可以完成此操作。 我在SPARC / Solaris 9上看到了与Sun编译器类似的行为。 实验表明,定义为_Bool或unsigned多个位字段可以打包到单个字节内的相邻位(实际上是必需的),因此位字段本身没有严格的对齐要求。 我理解结构成员的布局主要是实现定义的,我不相信gcc的行为违反了C标准。 […]

避免gccfunction序幕开销?

我最近遇到了很多函数,其中gcc在x86上生成了非常糟糕的代码。 它们都符合以下模式: if (some_condition) { /* do something really simple and return */ } else { /* something complex that needs lots of registers */ } 将简单的情况看作是一个非常小的东西,以至于一半或更多的工作花在推动和弹出不会被修改的寄存器上。 如果我手动编写asm,我会在复杂的情况下保存并恢复已保存的跨调用寄存器,并且在简单的情况下完全避免触及堆栈指针。 有没有什么方法可以让gcc变得更聪明并且自己做到这一点? 最好使用命令行选项,而不是源代码中的丑陋黑客… 编辑:为了使它具体化,这里有一些非常接近我正在处理的一些函数: if (buf->pos end) { return *buf->pos++; } else { /* fill buffer */ } 另一个: if (!initialized) { /* complex initialization procedure */ } […]

我怎么知道gcc是否同意某些东西是不稳定的?

考虑以下: volatile uint32_t i; 我如何知道gcc是否确实将我视为易变? 它将被声明为是因为没有附近的代码将修改它,并且它的修改可能是由于某些中断。 我不是世界上最差的汇编程序员,但我在电视上播放一个。 有人可以帮我理解它会有什么不同吗? 如果你采取以下愚蠢的代码: #include #include volatile uint32_t i; int main(void) { if (i == 64738) return 0; else return 1; } 将其编译为对象格式并通过objdump反汇编,然后在删除’volatile’后执行相同操作,没有区别(根据diff)。 volatile声明是否太接近于其检查或修改的位置,或者我在声明易失性时应该总是使用某种primefaces类型? 一些优化标志会影响这个吗? 请注意,我的愚蠢样本并不完全符合我的问题,我意识到这一点。 我只是试图找出gcc是否确实将变量视为易失性,所以我正在研究小型转储以试图找到差异。

gcc -lpthread不工作

我在我的系统中安装了ubuntu 11。 我有一个使用pthread库的ac程序。 即使我使用标志-lpthread进行编译,我也会收到错误的Undefined reference to sem_wait() 。 例如: gcc -lpthread prog.c 该程序适用于其他ubuntu安装。

编译C文件时不支持的x86-64指令集错误

我正在尝试按照此链接中的教程。 当我开始编写test.c文件的部分时,我尝试运行第一个编译行。 gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror test.c -o test.o 这是test.c的内容 __asm__(“.code16\n”); __asm__(“jmpl $0x0000, $main\n”); void main() { } 当我调用第一个编译行时,它会显示此错误。 test.c:1:0: error: CPU you selected does not support x86-64 instruction set __asm__(“.code16\n”); ^ 谁能告诉我为什么会这样? 如果可能的话,如何修复它? 我正在运行Ubuntu Desktop x64,请提前感谢您的帮助。 编辑: 我已将第一个编译行更改为: gcc -c -g -Os -m32 -ffreestanding -Wall -Werror test.c -o test.o 它似乎工作正常。 […]

如何帮助gcc矢量化C代码

我有以下C代码。 第一部分只是从标准中读入一个复数的矩阵,称为M矩阵。 有趣的部分是第二部分。 #include #include #include #include #include int main() { int n, m, c, d; float re, im; scanf(“%d %d”, &n, &m); assert(n==m); complex float M[n][n]; for(c=0; c<n; c++) { for(d=0; d<n; d++) { scanf("%f%fi", &re, &im); M[c][d] = re + im * I; } } for(c=0; c<n; c++) { for(d=0; d<n; d++) { […]

gcc是否使用英特尔的SSE 4.2指令进行文本处理?

我在这里读到英特尔推出了加速字符串处理的SSE 4.2 instructions 。 从文章引用: SSE 4.2指令集首先在Intel的Core i7中实现,提供了字符串和文本处理指令(STTNI),它们利用SIMD操作处理字符数据。 尽管这些指令最初是为加速字符串,文本和XML处理而设计的,但这些指令的强大新function在这些域之外是有用的,值得重新审视众多应用程序的搜索和识别阶段,以利用STTNI来提高性能 gcc是否可以使用这些说明? 如果是这样,哪个版本? 如果没有,是否有任何开源库提供此function?

为什么INT64_MIN的定义不同? 为什么他们的行为不同?

我公司的stdint.h标题是: #define INT64_MIN -9223372036854775808LL 但在我项目的一些代码中,程序员写道: #undef INT64_MIN #define INT64_MIN (-9223372036854775807LL -1) 然后他在代码中使用此定义。 该项目编译时没有警告/错误。 当我试图删除他的定义并使用默认定义时,我得到了: error: integer constant is so large that it is unsigned 这两个定义似乎是等价的。 为什么一个编译好,另一个失败?