如果使用64位UNIX操作系统,将数组大小定义为8的倍数是否有任何优势?我打算使用此数组从共享内存加载数据.因此,操作系统和页面大小可能存在依赖关系.
如何在gcc中明确禁用对定义变量的对齐?
拿这个代码:
typedef struct{
unsigned long long offset;
unsigned long long size;
unsigned long type;
unsigned long acpi;
}memstruct;
memstruct *memstrx;
Run Code Online (Sandbox Code Playgroud)
这将定义一个大小为24字节的结构.
我试过做:
memstrx=(void*)(0x502);
Run Code Online (Sandbox Code Playgroud)
所以
&memstrx[0]应该有一个值
&memstrx[1]0x502,0x51A
&memstrx[2],0x532
......依此类推.
但事情似乎并不正确.
相反,
&memstrx[1]时,显示的0x522地址
&memstrx[2],0x542
&memstrx[3],0x552
... 等等等等.
我怀疑GCC已经隐式地将结构重新调整为32个字节(从24个字节),强制a(每个条目的64位对齐).我真的不希望这种行为只适用于这种结构.我该如何告诉GCC不要对齐那个结构?
我正在使用定义为16位整数的二维数组
int16_t e[MAX_SIZE*MAX_NODE][MAX_SIZE];
int16_t C[MAX_SIZE][MAX_SIZE];
Run Code Online (Sandbox Code Playgroud)
其中Max_SIZE和MAX_NODE是恒定值.我不是一个专业的程序员,但是在StackOverflow的人的帮助下,我设法写了一段代码,在我的数据上部署SSE指令并实现了显着的加速.目前,我正在使用不需要数据对齐的内在函数(主要_mm_loadu_si128和_mm_storeu_si128).
for (b=0; b<n; b+=8){
v1 = _mm_loadu_si128((__m128i*)&C[level][b]); // level defined elsewhere.
v2 = _mm_loadu_si128((__m128i*)&e1[node][b]); // node defined elsewhere.
v3 = _mm_and_si128(v1,v2);
_mm_storeu_si128((__m128i*)&C[level+1][b],v3);
}
Run Code Online (Sandbox Code Playgroud)
当我将内在函数更改为对齐数据(即_mm_load_si128和_mm_store_si128)时,我得到运行时错误,这导致我假设我的数据没有正确对齐.
我现在的问题是,如果我的数据没有正确对齐,我如何调整它以便能够使用相应的内在函数?我想因为整数是16位,它们会自动对齐.但我似乎错了!
任何有关这方面的见解将受到高度赞赏.
谢谢!
我的代码给出了一条错误消息,我试图找出它的原因.为了更容易找到问题,我删除了显然与导致错误消息无关的代码.如果您能告诉我为什么以下简单代码会产生错误消息,那么我认为我应该能够修复原始代码:
#include "cuComplex.h"
#include <cutil.h>
__device__ void compute_energy(void *data, int isample, int nsamples) {
cuDoubleComplex * const nminusarray = (cuDoubleComplex*)data;
cuDoubleComplex * const f = (cuDoubleComplex*)(nminusarray+101);
double * const abs_est_errorrow_all = (double*)(f+3);
double * const rel_est_errorrow_all = (double*)(abs_est_errorrow_all+nsamples*51);
int * const iid_all = (int*)(rel_est_errorrow_all+nsamples*51);
int * const iiu_all = (int*)(iid_all+nsamples*21);
int * const piv_all = (int*)(iiu_all+nsamples*21);
cuDoubleComplex * const energyrow_all = (cuDoubleComplex*)(piv_all+nsamples*12);
cuDoubleComplex * const refinedenergyrow_all = (cuDoubleComplex*)(energyrow_all+nsamples*51);
cuDoubleComplex * const btplus_all = (cuDoubleComplex*)(refinedenergyrow_all+nsamples*51);
cuDoubleComplex * const btplus = btplus_all+isample*21021; …Run Code Online (Sandbox Code Playgroud) 我使用objdump在32位Linux上反汇编一些ELF文件.
asm文件采用Intel格式.
在反汇编文件中,我注意到一些内存插槽如下:
80483ed: c7 44 24 18 07 00 00 mov DWORD PTR [esp+0x18],0x7
80483f4: 00
80483f5: c7 44 24 1c 0c 00 00 mov DWORD PTR [esp+0x1c],0xc
80483fc: 00
80483fd: c7 44 24 20 01 00 00 mov DWORD PTR [esp+0x20],0x1
8048404: 00
8048405: c7 44 24 24 fe ff ff mov DWORD PTR [esp+0x24],0xfffffffe
804840c: ff
Run Code Online (Sandbox Code Playgroud)
原始的汇编文件是:
mov DWORD PTR [esp+24], 7
mov DWORD PTR [esp+28], 12
mov DWORD PTR [esp+32], 1
mov DWORD PTR [esp+36], -2 …Run Code Online (Sandbox Code Playgroud) linux assembly memory-management memory-alignment disassembly
我在文件中有一些二进制数据,并将文件加载到内存中char* data.现在我知道,例如在偏移123处开始a struct something.
执行以下操作是否安全
(struct something*) (data + 123) // ??&data [123]??
Run Code Online (Sandbox Code Playgroud)
然后访问结构的成员.或者我应该做些什么
struct something record;
memcpy (&record, data + 123, sizeof (struct something) );
Run Code Online (Sandbox Code Playgroud)
甚至是完全不同的东西?
我的问题主要是因为我对"记忆对齐","词边界"等有一些模糊的回忆......
我正在使用IAR(C编译器)来编程TI芯片(16位MCU).
我有以下结构,
//I use union mainly because sometimes I use the 2 bytes word value
// and sometimes I only use one byte (either a or b)
typedef union {
uint16_t address;
struct
{
uint8_t parta;
uint8_t partb;
} details;
} address_t;
Run Code Online (Sandbox Code Playgroud)
然后我有以下mac地址定义,
typedef struct
{
uint8_t frame_type;
uint8_t sequence_number;
address_t source_address;
} mac_header_t;
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.
当我通过无线电接收数据包时,它存储在缓冲区数组中.
uint8_t buffer[MAX_PACKET_LEN];
//the first byte is packet length, mac address follows
mac_header_t *header = (mac_header_t *)(buffer + 1);
Run Code Online (Sandbox Code Playgroud)
奇怪的事情发生了,
//The packet is say
// …Run Code Online (Sandbox Code Playgroud) 我有一个巨大的结构,有不同类型的成员.我知道成员根据他们的类型对齐.
无论如何都要找出差距在哪里?
我的意思是我有兴趣知道编译器在哪些成员之间插入了一个间隙(当然差距是多少).
考虑以下程序:
#include <iostream>
struct __attribute__((__packed__)) mystruct_A
{
char a;
int b;
char c;
}x;
int main()
{
std::cout<<sizeof(x)<<'\n';
}
Run Code Online (Sandbox Code Playgroud)
从这个我明白了以下几点:
我在32位环境中,正在使用Windows 7 OS。链接问题的第一个答案说,以上代码将在32位体系结构上生成6号大小的结构。
但是,当我使用g ++ 4.8.1对其进行编译时,它的输出为9。那么,结构打包在这里不会完全发生吗?为什么输出中要多出3个字节?sizeof char始终为1。在我的编译器中,sizeof int为4。因此,压缩结构时,以上结构的sizeof应该为1 + 4 + 1 = 6。
处理器有任何作用还是仅取决于编译器?
我试图了解内存对齐在C++中是如何工作的.
如果我理解正确,如果n是指针的二进制表示中的尾随零的数量,则指针对齐到2 ^ n个字节.但是,以下程序:
#include <bitset>
#include <cstdint>
#include <iostream>
#include <climits>
#include <cassert>
template <typename T>
std::size_t nTrailingZeros(const T* pointer)
{
assert(CHAR_BIT == 8);
std::bitset<8*sizeof(std::uintptr_t)> bits(reinterpret_cast<std::uintptr_t>(pointer));
std::size_t nZeroes{};
while (nZeroes < bits.size() && !bits[nZeroes])
{
++nZeroes;
}
return nZeroes;
}
struct alignas(64) A {int x;};
int main()
{
std::cout << "Alignment: " << alignof (A) << std::endl;
std::cout << "Trailing zeros: " << nTrailingZeros (new A) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
对齐:64尾随零:4
在我的电脑上.
我究竟做错了什么?我期望至少6个尾随零,但我只得到4(建议16字节对齐).