标签: memory-alignment

C++:严格别名与联合滥用

提前道歉,这可能是一个蹩脚的第一篇文章.虽然这个主题有很多材料,但对我来说很少是明确的和/或可理解的.

我有一个AlignedArray模板类,可以在堆上动态分配任意对齐的内存(我需要为AVX程序集例程进行32字节对齐).这需要一些丑陋的指针操作.

Agner Fog在cppexamples.zip中提供了一个样本类,它滥用了一个联合(http://www.agner.org/optimize/optimization_manuals.zip).但是,我知道写一个联盟的一个成员然后从另一个成员读取会导致UB.

AFAICT可以安全地将任何指针类型别名为a char *,但只能在一个方向上.这是我理解变得模糊的地方.这是我AlignedArray 课程的精简版(基本上是对Agner的重写,以帮助我理解):

template <typename T, size_t alignment = 32>
class AlignedArray
{
    size_t m_size;
    char * m_unaligned;
    T * m_aligned;

public:
    AlignedArray (size_t const size)
        : m_size(0)
        , m_unaligned(0)
        , m_aligned(0)
    {
        this->size(size);
    }

    ~AlignedArray ()
    {
        this->size(0);
    }

    T const & operator [] (size_t const i) const { return m_aligned[i]; }

    T & operator [] (size_t const i) { return m_aligned[i]; }

    size_t const size () { …
Run Code Online (Sandbox Code Playgroud)

c++ pointers memory-alignment unions

11
推荐指数
1
解决办法
987
查看次数

alignas说明符是否与'new'一起使用?

我的问题很简单;

alignas说明符是否与'new'一起使用?也就是说,如果一个struct定义为对齐,那么在分配new时它是否会对齐?

c++ memory-alignment new-operator c++11

11
推荐指数
2
解决办法
4719
查看次数

为什么-Wcast-align没有警告在x86上从char*转换为int*?

我知道gcc有一个选项-Wcast-align,只要指针被转换就会发出警告,以便增加目标所需的对齐.

这是我的计划:

char data[10];
int ptr = *((int *)data);
Run Code Online (Sandbox Code Playgroud)

在我的机器上,数据的对齐要求是1,而ptr是8.

为什么我没有收到警告?

可能是因为我正在为x86编译吗?

c memory-alignment gcc-warning typecasting-operator

11
推荐指数
1
解决办法
6922
查看次数

如何解决AVX加载/存储操作的32字节对齐问题?

我在使用时遇到对齐问题 ymm寄存器,一些代码片段对我来说似乎很好.这是一个最小的工作示例:

#include <iostream> 
#include <immintrin.h>

inline void ones(float *a)
{
     __m256 out_aligned = _mm256_set1_ps(1.0f);
     _mm256_store_ps(a,out_aligned);
}

int main()
{
     size_t ss = 8;
     float *a = new float[ss];
     ones(a);

     delete [] a;

     std::cout << "All Good!" << std::endl;
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,sizeof(float)4在我的架构(英特尔(R)至强(R)CPU E5-2650 V2 @ 2.60GHz),我与编译gcc使用-O3 -march=native标志.当然,错误会随着未对齐的内存访问而消失,即指定_mm256_storeu_ps.我在xmm寄存器上也没有这个问题,即

inline void ones_sse(float *a)
{
     __m128 out_aligned = _mm_set1_ps(1.0f);
     _mm_store_ps(a,out_aligned);
}
Run Code Online (Sandbox Code Playgroud)

我做了什么愚蠢的事吗?解决这个问题的方法是什么?

c++ sse memory-alignment avx c++11

11
推荐指数
2
解决办法
4468
查看次数

GCC上#pragma pack(push,n)/ #pragma pack(pop)和__attribute __((__ packed __,aligned(n)))之间有什么区别?

特别是在GCC上(也就是说,用GCC编译),以下两种方式有什么区别?

struct foo1 {
    char a;
    int b;
} __attribute__((__packed__, aligned(n) ));
Run Code Online (Sandbox Code Playgroud)

和:

#pragma pack(push, n)
struct foo2 {
    char a;
    int b;
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)

它们看起来表现不同:

foo1 f1;
foo2 f2;

int& i1 = f1.b; // ok
int& i2 = f2.b; // cannot bind packed field 'f2.foo2::b' to 'int&'
Run Code Online (Sandbox Code Playgroud)

为什么一个而不是另一个有错误?内存布局至少相同吗?

c c++ gcc memory-alignment

11
推荐指数
1
解决办法
9325
查看次数

`std :: alignment_of`与`alignof`

我偶然发现了std::alignment_of类型特征,以及即将成为朋友的类型特征std::alignment_of_v.它们似乎专门设计为等同于普通调用alignof,并且未来添加_v帮助程序表明它不仅仅是遗留位.

有什么用的std::alignment_of(_v),当我们有alignof

c++ memory-alignment alignof c++17

11
推荐指数
2
解决办法
1104
查看次数

如何对齐std :: array包含的数据?

既然std::array不允许更改其分配器,是否有办法确保指向数据地址的指针是对齐的?

例如,在GNU g ++ 4.8.4和6.1.0中,代码如下

#include <array>
#include <iostream>

int main(void)
{
  std::array<bool, 10> a;
  std::array<char, 10> b;
  std::array<int,10> c;
  std::array<long long, 10> d;
  std::array<float, 10> e;
  std::array<double, 10> f;

  std::cout << "array<bool,10>.data()       = " << a.data() << std::endl;
  std::cout << "array<char,10>.data()       = " << (void*) b.data() << std::endl;
  std::cout << "array<int,10>.data()        = " << c.data() << std::endl;
  std::cout << "array<long long, 10>.data() = " << d.data() << std::endl;
  std::cout << "array<float, 10>.data()     = " << e.data() << …
Run Code Online (Sandbox Code Playgroud)

c++ arrays std memory-alignment c++11

11
推荐指数
1
解决办法
2849
查看次数

优化golang中的数据结构/字对齐填充

与我在C++中学到的相似,我认为填充会导致两个结构的实例大小不同.

type Foo struct {
    w byte //1 byte
    x byte //1 byte
    y uint64 //8 bytes
}
type Bar struct {
    x byte //1 byte
    y uint64 //8 bytes
    w byte// 1 byte
}
func main() {
    fmt.Println(runtime.GOARCH)
    newFoo := new(Foo)
    fmt.Println(unsafe.Sizeof(*newFoo))
    newBar := new(Bar)
    fmt.Println(unsafe.Sizeof(*newBar))
}
Run Code Online (Sandbox Code Playgroud)

输出:

amd64
16
24
Run Code Online (Sandbox Code Playgroud)
  • 在定义struct成员时是否遵循经验法则?(如类型大小的升序/降序)
  • 是否有我们可以通过的编译时优化,可以自动处理这个?
  • 或者我不应该担心这一点?

struct padding go memory-alignment

11
推荐指数
2
解决办法
2998
查看次数

C++ 对齐 new[]

概述

当浏览operator new、operator new[] - cppreference.com时,我们似乎有很多选项来分配具有特定对齐要求的对象数组。但是,没有指定如何使用它们,而且我似乎找不到正确的 C++ 语法。

我可以以某种方式显式调用该运算符,还是编译器会自动推断重载?:

void* operator new[]( std::size_t count, std::align_val_t al );
Run Code Online (Sandbox Code Playgroud)

看看Bartek的编码博客,似乎编译器会根据对齐要求是否大于__STDCPP_DEFAULT_NEW_ALIGNMENT__(在64位机器上通常为16)自动选择重载。

问题

在某些情况下是否可以手动为new操作员选择重载?有时我可能希望分配的块以某种方式对齐(我假设对齐始终是 2 的幂,并且可能大于 16)。

编译器的选择

在可预见的将来,我可能会使用 GCC 和 C++ >= 17。

c++ memory-alignment c++17

11
推荐指数
1
解决办法
1万
查看次数

.NET Core 中类内部的结构对齐

我试图理解为什么只包含 int 的结构在类中占用 8 个字节的内存。

考虑以下代码;

static void Main()
{
    var rand = new Random();

    var twoIntStruct = new TwoStruct(new IntStruct(rand.Next()), new IntStruct(rand.Next()));
    var twoInt = new TwoInt(rand.Next(), rand.Next());

    Console.ReadLine();
}

public readonly struct IntStruct
{
    public int Value { get; }

    internal IntStruct(int value)
    {
        Value = value;
    }
}

public class TwoStruct
{
    private readonly IntStruct A;
    private readonly IntStruct B;

    public TwoStruct(
        IntStruct a,
        IntStruct b)
    {
        A = a;
        B = b;
    }
}

public class …
Run Code Online (Sandbox Code Playgroud)

c# memory struct memory-alignment .net-core

10
推荐指数
1
解决办法
776
查看次数