填充有/没有内在函数 C++

Posted

技术标签:

【中文标题】填充有/没有内在函数 C++【英文标题】:Fill with/without intrinsics C++ 【发布时间】:2012-12-15 01:32:03 【问题描述】:

我正在研究内在函数对性能的影响,我有点困惑:它们似乎根本没有影响!我试图用两个不同的函数填充一个双精度数组,但我看不出有什么区别。我通过调用 _aligned_malloc 并将对齐参数设置为 8 来分配数组。我使用 Visual Studio 2008 并在发布模式下编译,包括优化和不优化 (/O2 - /Od) 以及有和没有内在函数 (/Oi) - 所有四种组合。以下是两个不同的版本:

#ifdef _NO_INTRIN

void my_fill(double* vett, double value, int N)

    double* last = vett + N;
    while( vett != last)
    
        *vett++ = value;
    


#else

void my_fill(double* vett, double value, int N)

    double* last = vett + N;

    // set "classically" unaligned data, if any
    while( (0xF & (uintptr_t)vett) && vett != last )
        *vett++ = value;

    __m128d* vett_ = (__m128d*)vett;
    uintptr_t fff0 = ~0 << 4;
    // round address to nearest aligned data setting to zero least significant 4 bits
    __m128d* last_ = (__m128d*)( fff0 & (uintptr_t)last);
    // process until second-last element to manage odd values of N
    for( ; vett_ < last_-1; vett_++ )
    
        *vett_ = _mm_set1_pd(value);
    

    vett = (double*)vett_;
    while(vett != last)
        *vett++ = value;
    

#endif

作为最后一个规范,我将数据对齐到 8B 而不是 16,因为我计划在数组的不同部分以多线程方式执行此函数。所以,同样将数据对齐到 16B 我不能确定数组的所有部分都会对齐(例如 303 个元素,3 个线程,每个线程 101 个元素,第 1 部分对齐到 16B,第 2 部分从 @vett+101 开始*8 ==> 未对齐)。这就是我尝试实现与对齐无关的功能的原因。 我试图在我的 Intel Atom CPU N570 @ 1.66 GHz 上填充一个 1M 元素的数组,我总是得到相同的执行时间。那么......我的方法有什么问题?为什么我看不出差异?提前谢谢大家。

【问题讨论】:

你是如何准确测量执行时间的? 同时发布基准测试代码。 如果您在四个样本之间没有看到任何性能差异,无论是阳性还是阴性,那么您没有正确测量。 我不想读这个,因为你从一个非常特殊的编译器和平台的内在函数开始,你甚至没有用它来标记你的问题。 一种猜测是编译器编写者已经知道所有这些,并且无论您以何种方式编写代码都会处理任何问题。 【参考方案1】:

如果您不进行任何复杂的计算,而只是将固定值写入内存,那么您的程序速度可能会受到内存带宽的限制。 CPU 可以在内部以更快的速度生成值,但它受限于它可以将它们传输到 RAM 中的速率(尤其是在处理不适合 CPU 缓存的大内存区域时)

【讨论】:

以上是关于填充有/没有内在函数 C++的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual C++ 中删除 SSE2 内在函数

c++ SSE内在函数atan2

ARM NEON 没有 xor gcc 内在函数

__saturatef() 内在函数没有等效的双精度

在 C++ 中检查具有内在函数的 nan

如何在有或没有 SIMD 内在函数的情况下从 Zig 构建和链接到 CGLM