标签: memory-alignment

在numpy中获取页面对齐的内存

array有没有办法在页边界上分配 numpy 的数据部分(即数据) ?

出于我关心的原因,如果我在 Intel 设备上使用 PyOpenCL,并且我想使用 创建缓冲区CL_MEM_USE_HOST_PTR他们建议数据 1) 页面对齐,2) 大小为缓存行的倍数。

C 中有多种分配页对齐内存的方法,例如:aligned malloc() in GCC?

numpy memory-alignment opencl pyopencl

5
推荐指数
1
解决办法
921
查看次数

MOVAPS 访问未对齐的地址

出于某种原因,我的一个函数正在调用movaps带有未对齐参数的 SSE 指令,这会导致崩溃。它发生在函数的第一行,其余的都需要在那里发生崩溃,但为了清楚起见省略了。

Vec3f CrashFoo(
    const Vec3f &aVec3,
    const float  aFloat,
    const Vec2f &aVec2)
{
    const Vec3f vecNew =
        Normalize(Vec3f(aVec3.x, aVec3.x, std::max(aVec3.x, 0.0f)));

    // ...
}
Run Code Online (Sandbox Code Playgroud)

这是我从调试主要调用它的方式:

int32_t main(int32_t argc, const char *argv[])
{
    Vec3f vec3{ 0.00628005248f, -0.999814332f, 0.0182171166f };
    Vec2f vec2{ 0.947231591f, 0.0522233732f };
    float floatVal{ 0.010f };

    Vec3f vecResult = CrashFoo(vec3, floatVal, vec2);

    return (int32_t)vecResult.x;
}
Run Code Online (Sandbox Code Playgroud)

这是从CrashFoo函数开头到崩溃行的反汇编:

00007FF7A7DC34F0  mov         rax,rsp  
00007FF7A7DC34F3  mov         qword ptr [rax+10h],rbx  
00007FF7A7DC34F7  push        rdi  
00007FF7A7DC34F8  sub         rsp,80h  
00007FF7A7DC34FF  movaps      xmmword …
Run Code Online (Sandbox Code Playgroud)

c++ sse memory-alignment disassembly visual-studio-2013

5
推荐指数
1
解决办法
3416
查看次数

reinterpret_cast 和结构对齐

是否有任何安全的方法可以将整数转换为结构?

举个例子:

struct Colour
{
    uint8_t A;
    uint8_t R;
    uint8_t G;
    uint8_t B;
};
Run Code Online (Sandbox Code Playgroud)

我转换为整数或从整数转换:

uint32_t myInteger
Colour* myColour = reinterpret_cast<Colour*>(&myInteger);
uint32_t* myInteger2 = reinterpret_cast<uint32_t*>(myColour);
Run Code Online (Sandbox Code Playgroud)

如果我的结构被填充,那么这将不起作用,有什么方法可以保证它有效吗?

我知道这可能不是标准的,但我更喜欢支持主要编译器(Visual Studio 和 GCC)而不是一些位移解决方法,这里已经回答了:Type cast struct to integer c++

c++ memory-alignment reinterpret-cast

5
推荐指数
1
解决办法
2633
查看次数

查找下一个对齐的内存地址

根据我对维基百科的理解,我可以通过以下按位运算找到具有正确对齐方式的下一个最接近元素的索引。

Assuming the address of the 1st element has the correct alignment.
Assuming the index_alignment is a power of 2.
new_index = (current_index + index_alignment - 1) & ~(index_alignment - 1).
new_address = address_of_1st_element + new_index
index_alignment is 16 bytes/sizeof(type of element) for SSE.
Run Code Online (Sandbox Code Playgroud)

是否可以直接在地址上使用它来从任何给定地址找到下一个最接近的对齐地址?(这样比较快吗?)

为了快速做到这一点,我正在考虑以下事项。

new_address = (current_address + alignment - 1) & ~(alignment -1)
alignment here is 16 for SSE.
Run Code Online (Sandbox Code Playgroud)

当我实现这个时,我发现以下代码无法编译...

根据 Salva 和 Rotem 的建议修复了代码

#include <iostream>
#include <stdint.h>
#define ALIGNMENT 16
using namespace std; …
Run Code Online (Sandbox Code Playgroud)

c++ bit-manipulation memory-alignment

5
推荐指数
1
解决办法
3520
查看次数

使用本征和std :: vector的SIGSEGV

我知道将Eigen类型与动态内存结合使用时会出现对齐问题。因此,我决定Eigen::DontAlign 根据此页面禁用向量化,但是以下代码仍在执行时一致地引发SIGSEGV。如果有人可以阐明为什么会发生,我会很高兴。从我的角度来看,使用Eigen::DontAlign应该使我摆脱了对齐的复杂性。

#include <Eigen/Dense>
#include <vector>

int main()
{
    using vec_t = Eigen::Matrix< double, 4, 1, Eigen::DontAlign >;
    std::vector< vec_t > foo;
    foo.emplace_back( 0.0, 0.0, 0.0, 1.0 );
    vec_t vec{ -4.0, 1.0, 3.0, 1.0 };
    foo.push_back( vec );
}
Run Code Online (Sandbox Code Playgroud)

GDB输出:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000408bed in Eigen::internal::evaluator<Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 2, 4, 1> > >::packet<0, double __vector(4)>(long long, long long) const (this=0x22fa90, row=0, col=0)
    at C:/Dev/Eigen/Eigen/src/Core/CoreEvaluators.h:197
197           return ploadt<PacketType, LoadMode>(m_data + row + col * …
Run Code Online (Sandbox Code Playgroud)

c++ vectorization memory-alignment eigen c++11

5
推荐指数
1
解决办法
715
查看次数

了解堆栈对齐强制执行

考虑以下 C 代码:

#include <stdint.h>

void func(void) {
   uint32_t var = 0;
   return;
}
Run Code Online (Sandbox Code Playgroud)

-O0GCC 4.7.2 为上述代码生成的未优化(即:选项)汇编代码是:

func:
    pushl %ebp
    movl %esp, %ebp
    subl $16, %esp
    movl $0, -4(%ebp)
    nop
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

根据堆栈对准要求所述的系统V ABI,堆栈必须由16个字节每之前对准call指令(该堆栈边界是默认的16个字节时不与该选项改变-mpreferred-stack-boundary)。因此,在函数调用之前,ESP 16的结果必须为零。

记住这些堆栈对齐要求,我假设在执行leave指令之前以下堆栈的状态表示是正确的:

Size (bytes)       Stack          ESP mod 16      Description
-----------------------------------------------------------------------------------

             |     . . .      |             
             ------------------........0          at func call
         4   | return address |
             ------------------.......12          at func entry
         4   |   saved …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc abi memory-alignment

5
推荐指数
1
解决办法
1333
查看次数

联合内部结构的填充如何工作?

我有以下内容:

#include <stdio.h>

typedef union u_data
{
        struct
        {
                int a;
                int b;
                int c;
        };
                int elem[3];
}       my_data;

int     main(void)
{
        my_data data;

        data.a = 3;
        data.b = 5;
        data.c = -3;
        printf("%d, %d, %d\n", data.elem[0], data.elem[1], data.elem[2]);
}
Run Code Online (Sandbox Code Playgroud)

它按照我的预期输出:3, 5, -3

但是我知道结构中可以有填充,所以这是否意味着结构中的元素可能并不总是与数组对齐?

c struct padding memory-alignment unions

5
推荐指数
1
解决办法
1391
查看次数

将数据直接 memcpy 到联合体而不是其特定成员之一是否安全?

说我有一个这样的工会

union blah {
    foo f;
    bar b;
};
Run Code Online (Sandbox Code Playgroud)

其中 和foo都是bar可简单复制的。这样做安全吗:

blah b;
foo f;
memcpy(&b, &f, sizeof(f));
Run Code Online (Sandbox Code Playgroud)

然后b.f作为活跃的工会成员使用?或者,我是否必须 memcpy 到特定的工会成员,如下所示:

memcpy(&b.f, &f, sizeof(f));
Run Code Online (Sandbox Code Playgroud)

我在实践中担心这一点的原因是因为我将不得不编写一个大致如下的函数:

template<int c>
void init_union(blah& b, typename type_family<c>::type const& t) {
    switch (c) {
    case 0:
        memcpy(&b.p0, &t, sizeof(t));
        break;
    case 1:
        memcpy(&b.p1, &t, sizeof(t));
        break;
    // etc.
    }
}
Run Code Online (Sandbox Code Playgroud)

但我宁愿能够跳过整个 switch 语句并只写这个:

template<int c>
void init_union(blah& b, typename type_family<c>::type const& t) {
    memcpy(&b, &t, sizeof(t));
}
Run Code Online (Sandbox Code Playgroud)

c++ memory-alignment memcpy unions language-lawyer

5
推荐指数
1
解决办法
1935
查看次数

为什么在我的实现中所有数组都对齐到 16 个字节?

我非常简单的代码如下所示

#include <iostream>
#include <stdalign.h>

int main() {
    char array_char[2] = {'a', 'b'};
    float array_float[2] = {1, 2};
    std::cout << "alignof(array_char): " << alignof(array_char) << std::endl;
    std::cout << "alignof(array_float): " << alignof(array_float) << std::endl;
    std::cout << "address of array_char: " << (void *) array_char << std::endl;
    std::cout << "address of array_float: " << array_float << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这段代码的输出是

alignof(array_char): 1

alignof(array_float): 4

array_char 的地址:0x7fff5e8ec580

array_float 的地址:0x7fff5e8ec570

alignof算子的结果在意料之中,但是两个数组的真实地址并不一致。无论我尝试了多少次,地址总是 16 字节对齐。

我在 Ubuntu 16.04 和 Intel CORE i5 第 7 代 …

c++ memory-alignment

5
推荐指数
1
解决办法
157
查看次数

获取处理器的内存粒度

如何在C中获取CPU的内存粒度

假设我想分配一个数组,其中所有元素都正确内存对齐。我可以将每个元素填充到特定大小 N 来实现这一点。我怎么知道N的值?

注意:我正在尝试创建一个内存池,其中每个插槽都是内存对齐的。任何建议将不胜感激。

c memory-management memory-alignment granularity

5
推荐指数
1
解决办法
162
查看次数