Tag: alignment

在C中解析/读取位图文件

我正在尝试制作一个程序来读取位图文件中的数据(.bmp,Windows文件格式,8位)。 现在我一直在图像数据之前阅读标题。 我使用了bmp的规范,我在这里找到了这些结构来保存bmp的文件头,信息头和图像数据: typedef struct { unsigned char fileMarker1; unsigned char fileMarker2; unsigned int bfSize; uint16_t unused1; uint16_t unused2; unsigned int imageDataOffset; } FILEHEADER; typedef struct { unsigned int biSize; int width; int height; uint16_t planes; uint16_t bitPix; unsigned int biCompression; unsigned int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; unsigned int biClrUsed; unsigned int biClrImportant; } […]

如何告诉GCC指针参数总是双字对齐?

在我的程序中,我有一个函数,它做一个简单的向量加法c[0:15] = a[0:15] + b[0:15] 。 function原型是: void vecadd(float * restrict a, float * restrict b, float * restrict c); 在我们的32位嵌入式架构上,有一个加载/存储双字加载/存储选项,如: r16 = 0x4000 ; strd r0,[r16] ; stores r0 in [0x4000] and r1 in [0x4004] GCC优化器识别循环的向量性质并生成代码的两个分支 – 一个用于3个数组是双字对齐的情况(因此它使用双重加载/存储指令)而另一个用于数组的情况是字对齐的(它使用单个加载/存储选项)。 问题是地址对齐检查相对于加法部分是昂贵的,我想通过暗示编译器a,b和c总是8对齐来消除它。 是否有一个修饰符添加到指针声明中以告诉编译器? 用于调用此函数的数组具有aligned(8)属性,但它不会反映在函数代码本身中。 是否可以将此属性添加到函数参数中?

如果它们是16字节对齐,是否可以直接将浮点数转换为__m128?

如果它们是16字节对齐的话,将浮点数直接转换为__m128是否安全/可行/可取? 我注意到使用_mm_load_ps和_mm_store_ps来“包装”原始数组会增加很大的开销。 我应该注意哪些潜在的陷阱? 编辑: 使用加载和存储指令实际上没有开销,我得到了一些数字混合,这就是为什么我有更好的性能。 即使你能够在__m128实例中使用原始内存地址进行一些HORRENDOUS修改,当我运行测试时,如果没有_mm_load_ps指令则需要TWICE AS LONG完成,可能会回退到一些故障安全代码路径。

确定与其成员相关的C / C ++结构的对齐方式

如果已知结构构件的对齐,是否可以找到结构类型的对齐? 例如。 对于: struct S { a_t a; b_t b; c_t c[]; }; 是S = max的对齐(alignment_of(a),alignment_of(b),alignment_of(c))? 在互联网上搜索我发现“对于结构化类型,其任何元素的最大对齐要求决定了结构的对齐”(在每个程序员应该知道的内存中 )但我在标准中找不到任何类似的东西(最新)草稿更准确)。 编辑:非常感谢所有答案,特别是罗伯特·甘博,他对原始问题和其他贡献者提供了非常好的答案。 简而言之: 为了确保结构构件的对准要求,结构的对准必须至少与其最严格构件的对准一样严格。 至于确定结构的对齐方式,我们提出了一些选项,经过一些研究,我发现了这个: c ++ std :: tr1 :: alignment_of 尚未标准,但关闭(技术报告1),应该在C ++ 0x中 最新草案中存在以下限制:前提条件:T应为完整类型,引用类型或未知范围的数组,但不应为函数类型或(可能是cv-qualified)void。 这意味着我使用C99灵活数组的用例不起作用(这并不奇怪,因为灵活的数组不是标准的c ++) 在最新的c ++草案中,它是用新关键字的术语定义的 – alignas(这具有相同的完整类型要求) 在我看来,如果c ++标准曾经支持C99灵活数组,那么要求可以放宽(结构与灵活数组的对齐不应该根据数组元素的数量而改变) c ++ boost :: alignment_of 主要是tr1替代品 似乎是专门针对void而在这种情况下返回0(这在c ++草案中是禁止的) 开发人员注意:严格来说,你应该只依赖于ALIGNOF(T)的值是T的真正对齐的倍数,尽管在实践中它确实在我们所知道的所有情况下计算了正确的值。 我不知道这是否适用于灵活的数组,它应该(可能不能正常工作,这解析为我平台上的编译器内在因此我不知道它在一般情况下会如何表现) Andrew Top提供了一个简单的模板解决方案,用于计算答案中的对齐方式 这似乎与boost正在做的非常接近(如果它小于计算的对齐,则boost会另外返回对象大小,因为我可以看到相同的通知) 这适用于灵活的数组 […]

如何在C中对齐这样的数字?

我需要将C中的一系列数字与printf()对齐,如下例所示: ——-1 ——-5 ——50 —–100 —-1000 当然,所有这些之间都有数字,但它与手头的问题无关……哦,将破折号视为空格,我使用破折号,因此更容易理解我想要的东西。 我只能做到这一点: —-1— —-5— —-50– —-100- —-1000 或这个: —1 —5 –50 -100 1000 但这一切都不是我想要的,我只能使用printf()来实现第一个例子中显示的内容。 有可能吗? 编辑: 对不起的人,我匆忙,并没有很好地解释自己…我的最后一个例子和你的所有建议(使用像“%8d”这样的东西)不起作用,因为虽然最后一个数字是1000但它没有对于那件事,必须一直到1000甚至100或10。 无论要显示的位数,我最多只需要4个前导空格作为最大数字。 假设我必须显示从1到1000(A)和1到100(B)的数字,我使用“%4d”,这将是输出: A: —1 …. 1000 哪个是我想要的输出… B: —1 …. -100 这不是我想要的输出,我实际上想要这个: –1 … 100 但就像我说的,我不知道我必须打印的确切数字,它可以有1位数,它可以有2个,3个或更多,该函数应该为所有人准备。 我想要四个额外的前导空间,但那并不相关。 编辑2:似乎我想要的东西,我需要它的方式,这是不可能的(查看David Thornley和Blank Xavier的回答和我的评论)。 谢谢大家的时间。

CPU和数据对齐

请原谅我,如果你觉得这已被无数次回答,但我需要回答以下问题! 为什么数据必须对齐(在4字节/ 8字节/ 2字节边界上)? 这里我怀疑的是,当CPU具有地址线Ax Ax-1 Ax-2 … A2 A1 A0时,可以顺序寻址存储器位置。 那么为什么需要在特定边界对齐数据呢? 在编译代码和生成可执行代码时如何找到对齐要求? 如果例如数据对齐是4字节边界,那是否意味着每个连续字节位于模4偏移处? 我怀疑的是,如果数据是4字节对齐,那意味着如果一个字节是1004那么下一个字节是1008(或1005)?