c++ - 使用 SSE 内在函数注册短缺

标签 c++ memory sse cpu-registers

在这篇文章中 SSE load/store memory transactions我询问了显式寄存器内存事务和中间指针之间的区别。在实践中,中间指针表现出略高的性能,但是,从硬件方面不清楚什么是中间指针?如果创建了指针,是否意味着某些寄存器也被占用,或者寄存器的调用发生在某些 SSE 操作期间(例如_mm_mul)?

让我们考虑这个例子:

struct sse_simple
{
    sse_simple(unsigned int InputLength):
        Len(InputLength/4),
        input1((float*)_mm_malloc((float *)_mm_malloc(cast_sz*sizeof(float), 16))),
        input2((float*)_mm_malloc((float *)_mm_malloc(cast_sz*sizeof(float), 16))),
        output((float*)_mm_malloc((float *)_mm_malloc(cast_sz*sizeof(float), 16))),
        inp1_sse(reinterpret_cast<__m128*>(input1)),
        inp1_sse(reinterpret_cast<__m128*>(input2)),
        output_sse(reinterpret_cast<__m128*>(output))
    {}

    ~sse_simple()
    {
        _mm_free(input1);
        _mm_free(input2);
        _mm_free(output);
    }

    void func()
    {
        for(auto i=0; i<Len; ++i)
            output_sse[i] = _mm_mul(inp1_sse[i], inp2_sse[i]);
    }

    float *input1;
    float *input2;
    float *output; 

    __m128 *inp1_sse;
    __m128 *inp2_sse;
    __m128 *output_sse;

    unsigned int Len;
};

在上面的示例中,中间指针 inp1_sse、inp2_sse 和 output_sse 在构造函数中创建一次。如果我复制大量 sse_simple 对象(例如 50 000 或更多),这会导致寄存器短缺吗?

最佳答案

首先,寄存器是靠近计算单元(意味着访问非常快)的小型存储器。编译器尝试尽可能多地使用它们来加速计算,但当它不能使用内存时。由于寄存器中存储的内存量很小,通常寄存器仅在计算时用作临时变量。大多数时候,除了循环索引等临时变量外,所有内容最终都会存储在内存中……因此,寄存器不足只会减慢计算速度。

在计算过程中,指针存储在通用寄存器 (GPR) 中,无论它们指向 float 、 vector 还是其他,而 vector __m128 存储在特定寄存器中。

因此在您的示例中,树数组将存储在内存中,而行

output_sse[i] = _mm_mul(inp1_sse[i], inp2_sse[i]);

编译为:

movaps -0x30(%rbp),%xmm0    # load inp1_sse[i] in register %xmm0
movaps -0x20(%rbp),%xmm1    # load inp2_sse[i] in register %xmm1
mulps  %xmm1,%xmm0          # perform the multiplication the result is stored in %xmm0
movaps %xmm0,(%rdx)         # store the result in memory

如您所见,指针是使用寄存器 %rbp%rdx 存储的。

关于c++ - 使用 SSE 内在函数注册短缺,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17697031/

相关文章:

c - Linux SPARSEMEM 内存模型真的很稀疏吗?

vectorization - Xeon Phi 上的 loaddup_pd/unpacklo_pd

c - 如何将上位 double 浮点元素与 SSE 进行比较

c++ - 正则表达式误解或只是破坏了实现?

c++ - 为什么 concurrent_queue 是非阻塞的?

c++ - 适用于 Windows 7 的 OpenGL

c++ - Log4Cplus加载配置文件

C - 在 strdup() 之后释放内存

memory - CUDA 纹理内存空间

c++ - 如何使用 SSE/AVX 高效地执行 double/int64 转换?