标签: memory-alignment

使用auto关键字时,对齐16不受尊重?

使用VS2012进行编译并使用DirectXMath库,我遇到了一个问题,即编译器似乎没有对齐我的XMMATRIX.我将问题简化为以下内容.

#include <DirectXMath.h>
using namespace DirectX;

int _tmain(int argc, _TCHAR* argv[])
{
  auto m1 = XMMatrixIdentity();
  auto m2 = XMMatrixIdentity();

  auto t1 = XMMatrixTranspose( m1 ); // sometimes access violation occurs here
  auto t2 = XMMatrixTranspose( m2 ); // or sometimes here

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

反复重新运行代码有时会在第一次转置时导致"访问冲突读取位置0xFFFFFFFF",有时在第二次转置时.

我发现这是因为m1和m2没有正确对齐.用"XMMATRIX"替换"auto"似乎解决了这个问题,所以我的怀疑是一个编译器错误,但它也可能是我做错了,或者没有启用某些选项.

我的代码有问题还是编译错误?

c++ memory-alignment visual-c++ visual-studio-2012 directxmath

14
推荐指数
1
解决办法
1130
查看次数

未对齐的加载与未对齐的商店

简短的问题是,如果我有一个带两个向量的函数.一个是输入,另一个是输出(无别名).我只能调整其中一个,我应该选择哪一个?

更长的版本是,考虑一个功能,

void func(size_t n, void *in, void *out)
{
    __m256i *in256 = reinterpret_cast<__m256i *>(in);
    __m256i *out256 = reinterpret_cast<__m256i *>(out);
    while (n >= 32) {
         __m256i data = _mm256_loadu_si256(in256++);
         // process data
         _mm256_storeu_si256(out256++, data);
         n -= 32;
    }
    // process the remaining n % 32 bytes;
}
Run Code Online (Sandbox Code Playgroud)

如果inout都是32字节对齐,那么使用vmovdqu而不是代价vmovdqa.最糟糕的情况是两者都是未对齐的,并且四分之一的加载/存储将跨越缓存行边界.

在这种情况下,我可以通过在进入循环之前先处理几个元素将其中一个与高速缓存行边界对齐.但是,问题是我应该选择哪个?在未对齐的加载和存储之间,哪一个更糟?

c++ performance x86 memory-alignment avx

14
推荐指数
1
解决办法
612
查看次数

禁止在x86/x86_64上进行未对齐的内存访问

我想在x86/x86_64上使用禁止的未对齐内存访问来模拟系统.是否有一些调试工具或特殊模式来执行此操作?

我想在使用为SPARC或其他类似CPU设计的软件(C/C++)时,在几台x86/x86_64 PC上运行许多(CPU密集型)测试.但是我对Sparc的访问是有限的.

据我所知,Sparc总是检查内存读写中的对齐是否自然(从任何地址读取一个字节,但只有当地址可被4整除时才允许读取4字节字).

可能是Valgrind还是PIN有这样的模式?还是特殊的编译模式?我正在寻找Linux非商业工具,但Windows工具也允许.

或者可能是EFLAGS中有秘密的CPU标志?

linux debugging x86 memory-alignment

13
推荐指数
3
解决办法
2423
查看次数

std :: tuple内存对齐

是否有关于元组伪成员的布局和内存对齐的正式规范?

反正有没有修改元组中类型的内存对齐?它是否受#pragma pack()指令的影响?

例如:

typedef std::tuple<uint8_t, uint32_t> myTuple;
Run Code Online (Sandbox Code Playgroud)

是否有任何规范说这将在内存中与以下相同:

#pragma pack() // Default packing
struct myStruct
{
    uint8_t first;
    uint32_t second;
}
Run Code Online (Sandbox Code Playgroud)

抱歉,如果这是一个愚蠢的问题,但我不完全理解模板的对齐.

编辑:我正在努力完成的例子

目前我有一些东西......

#pragma pack(push)
#pragma pack(4)
struct cTriangle
{
    uint32 Index[3];
};
#pragma pack(pop)

template <class T>
inline bool Read(cFileStream& fStream, std::vector<T>& vec)
{
    if (!vec.size())
        return true;

    // fStream.Read(void* pBuffer, size_t Size)
    // Just a wrapper around a binary ifstream really
    return fStream.Read(&vec[0], sizeof(T) * vec.size());
}

std::vector<cVector3> vPoint;
vPoint.resize(Verticies);
bool result = Read(FileStream, vPoint);
Run Code Online (Sandbox Code Playgroud)

如果我想为元编程目的使用typedef …

c++ tuples memory-alignment language-lawyer c++11

13
推荐指数
2
解决办法
5130
查看次数

我如何在C++ 03中可移植地实现对齐的堆栈存储?

在C++ 03代码中,我如何可移植地实现unsigned char[sizeof(T)]与给定类型具有相同大小和对齐的缓冲区T

例如:

template<class T>
void test()
{
    unsigned char buffer[sizeof(T)];   // <----- how do I ensure this is aligned?
    if (some_condition())
    {
        T *const obj = new(buffer) T();
        // ...
        obj->~T();
    }
    else { /* use 'buffer' for something else */ }
}
Run Code Online (Sandbox Code Playgroud)

这甚至是可能的,还是你被迫使用编译器扩展来实现它?

c++ memory-alignment placement-new

13
推荐指数
1
解决办法
546
查看次数

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

我正在编写一个带有32kbyte 8路组关联L2指令高速缓存的嵌入式 32系统.为了避免高速缓存抖动,我们以一种方式对齐函数,使得以高频率调用的一组函数的文本(想想中断代码)最终在单独的高速缓存集中.我们通过根据需要插入虚函数来实现这一点,例如

void high_freq1(void)
{
   ...
}

void dummy(void)
{
   __asm__(/* Silly opcodes to fill ~100 to ~1000 bytes of text segment */);
}

void high_freq2(void)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

这让我感到丑陋和不理想.我想做的是

  • __asm__完全避免使用纯C89(可能是C99)
  • 找到一种方法来创建dummy()GCC优化器不接触的所需间隔
  • dummy()spacer 的大小应该可以配置为4个字节的倍数.典型的间隔物为260至1000个字节.
  • 对于总共500个函数中的约50个函数,应该是可行的

我也愿意探索以一种方式放置一组选定函数的全新技术,这样它们就不会映射到相同的缓存行.链接器脚本可以执行此操作吗?

c gcc powerpc memory-alignment

13
推荐指数
1
解决办法
879
查看次数

C函数参数,内存对齐注意事项

在C中定义结构时,有关于填充的注意事项,如果结构大小是一个问题,则通常重新排列值以避免填充.(参见:结构填料和包装)

我的问题是:

相同(或类似)的规则是否适用于函数参数?...在安排参数以避免参数填充字节方面有什么好处吗?


  • 假设这不是inline(它不重要),或者static编译器可以重新排列参数的函数.

  • 接受现实世界可衡量的改善可能很小.

...实际上,如果函数调用开销是一个问题,可能值得内联函数.尽管如此,内联并不总是一个选项(例如库或函数指针).

c function memory-alignment

13
推荐指数
1
解决办法
862
查看次数

是否保证POD结构或标准布局类型的成员根据其对齐要求进行对齐?

给定POD结构(在C++ 03中)或标准布局类型(在C++ 11中),所有成员都具有基本对齐要求,是否保证每个成员根据其对齐要求进行对齐?

换句话说,对于m_k{ m0... mn}标准布局类型的所有成员S,

  struct S {
    T0 m0;
    T1 m1;
    ...
    TN mn;
  };
Run Code Online (Sandbox Code Playgroud)

是否保证评估以下表达式true

  (offsetof(S,m_k) % alignof(decltype(S::m_k))) == 0
Run Code Online (Sandbox Code Playgroud)

请给出C++ 03和C++ 11的答案,并引用标准的相关部分.支持C标准的证据也会有所帮助.


我对C++ 03标准(ISO/IEC 14882:2003(E))的阅读是关于POD结构中成员的对齐,除了第一个成员之外,它是静默的.相关段落是:

在规范的语言中,对象是"存储区域":

1.8 C + +对象模型[intro.object]

1.8/1 C++程序中的构造创建,销毁,引用,访问和操作对象.对象是存储区域....

根据对齐要求分配对象:

3.9类型[basic.types]

3.9/5对象类型具有对齐要求(3.9.1,3.9.2).完整对象类型的对齐是表示字节数的实现定义的整数值; 在满足其对象类型的对齐要求的地址处分配对象.

基本类型具有对齐要求:

3.9.1基本类型[basic.fundamental]

3.9.1/3对于每个有符号整数类型,存在相应的(但不同的)无符号整数类型:"unsigned char","unsigned short int","unsigned int"和"unsigned long int",每个它占用相同的存储量,并且具有与相应的有符号整数类型相同的对齐要求(3.9) ; ...

由于"实现对齐要求",可能会发生填充:

9.2班级成员[class.mem]

9.2/12声明没有插入访问说明符的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址.由访问说明符分隔的非静态数据成员的分配顺序未指定(11.1).实现对齐要求可能导致两个相邻成员不会立即分配 ; 因此,可能需要空间来管理虚拟功能(10.3)和虚拟基类(10.1).

9.2/12中的"已分配"一词与3.9/5中的"已分配"含义相同吗?规范中"分配"的大多数用法是指动态存储分配,而不是结构内部布局.使用可能在9.2/12中似乎意味着结构成员可能不严格要求3.9/5和3.9.1/3的对齐要求.

POD结构的第一个成员将根据结构的对齐要求进行对齐:

9.2/17指向POD结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然.[ 注意:因此,在POD-struct对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐.]

[重点在上述所有引文中加入.]

c++ memory-alignment language-lawyer c++11 c++03

13
推荐指数
2
解决办法
784
查看次数

是否保证类型T [x] [y]与C中的T [x*y]具有相同的存储器布局?

到目前为止,我认为它是,但在我了解到编译器可能填充数据以使其符合架构要求时,例如我有疑问.所以我想知道一个char[4][3]内存布局是否相同char[12].编译器可以在char[3]部件之后放置填充以使其对齐,这样整个数组实际上需要16个字节吗?

背景故事,库的一个函数在char*参数中占用一堆固定长度的字符串,因此它需要一个没有paddig的连续缓冲区,字符串长度可以是奇数.所以我认为我声明了一个char[N_STRINGS][STRING_LENGTH]数组,然后方便地填充它并通过将其传递给函数传递给它char*.到目前为止似乎有效.但我不确定这个解决方案是否可移植.

c memory-alignment multidimensional-array language-lawyer

13
推荐指数
3
解决办法
614
查看次数

C未定义的行为.严格别名规则或错误对齐?

我无法解释这个程序的执行行为:

#include <string> 
#include <cstdlib> 
#include <stdio.h>

typedef char u8;
typedef unsigned short u16;

size_t f(u8 *keyc, size_t len)
{
    u16 *key2 = (u16 *) (keyc + 1);
    size_t hash = len;
    len = len / 2;

    for (size_t i = 0; i < len; ++i)
        hash += key2[i];
    return hash;
}

int main()
{
    srand(time(NULL));
    size_t len;
    scanf("%lu", &len);
    u8 x[len];
    for (size_t i = 0; i < len; i++)
        x[i] = rand();

    printf("out %lu\n", f(x, len));
}
Run Code Online (Sandbox Code Playgroud)

因此,当使用带有gcc的-O3编译并使用参数25运行时,它会引发段错误.没有优化它工作正常.我已经对它进行了反汇编:它正在进行矢量化,并且编译器假定 …

c gcc strict-aliasing memory-alignment

13
推荐指数
3
解决办法
2368
查看次数