相关疑难解决方法(0)

如何仅使用标准库分配对齐的内存?

我刚刚完成了一项测试,作为求职面试的一部分,一个问题让我感到难过 - 甚至使用谷歌作为参考.我想看看stackoverflow工作人员可以用它做什么:

"memset_16aligned"函数需要传递给它的16byte对齐指针,否则它将崩溃.

a)如何分配1024字节的内存,并将其与16字节边界对齐?
b)执行memset_16aligned后释放内存.

{    
   void *mem;
   void *ptr;

   // answer a) here

   memset_16aligned(ptr, 0, 1024);

   // answer b) here    
}
Run Code Online (Sandbox Code Playgroud)

c memory-management

404
推荐指数
9
解决办法
17万
查看次数

如何告诉GCC指针参数始终是双字对齐的?

在我的程序中,我有一个功能,可以添加一个简单的向量c[0:15] = a[0:15] + b[0:15].功能原型是:

void vecadd(float * restrict a, float * restrict b, float * restrict c);
Run Code Online (Sandbox Code Playgroud)

在我们的32位嵌入式架构中,有一个加载/存储双字加载/存储选项,如:

r16 = 0x4000  ;
strd r0,[r16] ; stores r0 in [0x4000] and r1 in [0x4004]
Run Code Online (Sandbox Code Playgroud)

GCC优化器识别循环的向量性质并生成代码的两个分支 - 一个用于3个数组是双字对齐的情况(因此它使用双重加载/存储指令)而另一个用于数组的情况是字对齐的(它使用单个加载/存储选项).

问题是地址对齐检查相对于加法部分是昂贵的,我想通过暗示编译器a,b和c始终是8对齐来消除它.是否有一个修饰符添加到指针声明以告诉编译器?

用于调用此函数的数组具有aligned(8)属性,但它不会反映在函数代码本身中.是否可以将此属性添加到函数参数?

c gcc c99 alignment

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

gcc内存对齐pragma

gcc是否具有内存对齐编译指示,类似于#pragma vector aligned英特尔编译器?我想告诉编译器使用对齐的加载/存储指令优化特定的循环.为了避免可能的混淆,这不是结构包装.

例如:

#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
        for (int a = 0; a < int(N); ++a) {
            q10 += Ix(a,0,0)*Iy(a,1,1)*Iz(a,0,0);
            q11 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,1,0);
            q12 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,0,1);
            q13 += Ix(a,1,0)*Iy(a,0,0)*Iz(a,0,1);
            q14 += Ix(a,0,0)*Iy(a,1,0)*Iz(a,0,1);
            q15 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,1,1);
        }
Run Code Online (Sandbox Code Playgroud)

谢谢

memory optimization gcc pragma alignment

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

使用alignas语法苦苦挣扎

我正在尝试使用alignas作为类成员的指针,坦率地说,我不确定我应该把它放在哪里.

例如:

class A
{
private:
    int n;
    alignas(64) double* ptr;    

public:
    A(const int num) : n(num), ptr(new double[num])
    {}
};
Run Code Online (Sandbox Code Playgroud)

我希望能确保ptr的数据在64字节块上对齐.使用英特尔编译器,它没有.

有人能指出我正确的方向吗?

c++ icc c++11 alignas

8
推荐指数
1
解决办法
1069
查看次数

展开循环并使用矢量化进行独立求和

对于以下循环,如果我告诉它使用关联数学,例如,GCC将仅对循环进行矢量化-Ofast.

float sumf(float *x)
{
  x = (float*)__builtin_assume_aligned(x, 64);
  float sum = 0;
  for(int i=0; i<2048; i++) sum += x[i];
  return sum;
}
Run Code Online (Sandbox Code Playgroud)

这是装配 -Ofast -mavx

sumf(float*):
    vxorps  %xmm0, %xmm0, %xmm0
    leaq    8192(%rdi), %rax
.L2:
    vaddps  (%rdi), %ymm0, %ymm0
    addq    $32, %rdi
    cmpq    %rdi, %rax
    jne .L2
    vhaddps %ymm0, %ymm0, %ymm0
    vhaddps %ymm0, %ymm0, %ymm1
    vperm2f128  $1, %ymm1, %ymm1, %ymm0
    vaddps  %ymm1, %ymm0, %ymm0
    vzeroupper
    ret
Run Code Online (Sandbox Code Playgroud)

这清楚地表明循环已被矢量化.

但是这个循环也有一个依赖链.为了克服添加的延迟,我需要在x86_64上展开并执行至少三次部分和(不包括Skylake,需要展开八次并使用需要在Haswell和Broadwell上展开10次的FMA指令进行添加) .据我所知,我可以展开循环-funroll-loops.

这是装配-Ofast -mavx -funroll-loops.

sumf(float*):
    vxorps …
Run Code Online (Sandbox Code Playgroud)

c x86 gcc loop-unrolling auto-vectorization

7
推荐指数
1
解决办法
517
查看次数

gcc向量扩展中的未对齐加载/存储

我需要使用GCC向量扩展来访问未对齐的值

下面的程序崩溃了 - 包括clang和gcc

typedef int __attribute__((vector_size(16))) int4;
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;

int main()
{
        int v[64] __attribute__((aligned(16))) = {};
        int4p ptr = reinterpret_cast<int4p>(&v[7]);
        int4 val = *ptr;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我改变

typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
Run Code Online (Sandbox Code Playgroud)

typedef int __attribute__((vector_size(16),aligned(4))) int4u;
typedef int4u *int4up;
Run Code Online (Sandbox Code Playgroud)

生成的汇编代码是正确的(使用未对齐的加载) - 在clang和gcc中.

单一定义有什么问题或者我错过了什么?clang和gcc都可以是同一个bug吗?

注意:它发生在clang和gcc中

c++ gcc simd clang

3
推荐指数
1
解决办法
659
查看次数

GCC __attribute__ ((对齐 (8))) 不起作用

我在其他帖子中写过这个问题。虽然事实并非如此。

GCC编译器版本:4.8.3(适用于ARM)

代码摘录:

uint8_t data[4] __attribute__ ((aligned (8))) = {1,2,3,4};

int main()
{
    uint32_t p = 0;
    p = (uint32_t)&data[0];
    p = (uint32_t)&data[1];
    p = (uint32_t)&data[2];
    p = (uint32_t)&data[3];
}
Run Code Online (Sandbox Code Playgroud)

请注意,数据位于任何函数之外,因此不会堆栈中分配。

我看到的结果(调试时)是p536870912, 536870913, 536870914, 536870915;

我期待这样的事情:536870912, 536870920, 536870928, 536870936

任何帮助将非常感激。

c gcc

2
推荐指数
1
解决办法
4802
查看次数