是否可以使用std::vector自定义结构分配对齐的内存以便使用SIMD指令进行进一步处理?如果有可能,有Allocator没有人碰巧有这样的分配器,他可以分享?
如果我想std::vector用SSE 处理数据,我需要16字节对齐.我怎样才能做到这一点?我需要编写自己的分配器吗?或者默认分配器是否已经与16字节边界对齐?
目前我做以下事情:
// float *c_array = new float[1024];
void Foo::foo(float *c_array, size_t c_array_size) {
//std::vector<float> cpp_array;
cpp_array.assign(c_array, c_array + c_array_size);
delete [] c_array;
}
Run Code Online (Sandbox Code Playgroud)
如何优化此分配?我不想执行元素复制,只是交换指针.
我正在编写一些AVX代码,我需要从可能未对齐的内存中加载.我目前正在加载4个双打,因此我将使用内部指令_mm256_loadu_pd ; 我写的代码是:
__m256d d1 = _mm256_loadu_pd(vInOut + i*4);
Run Code Online (Sandbox Code Playgroud)
然后,我使用选项进行编译,-O3 -mavx -g然后使用objdump获取汇编代码以及带注释的代码和line(objdump -S -M intel -l avx.obj).
当我查看底层汇编程序代码时,我发现以下内容:
vmovupd xmm0,XMMWORD PTR [rsi+rax*1]
vinsertf128 ymm0,ymm0,XMMWORD PTR [rsi+rax*1+0x10],0x1
Run Code Online (Sandbox Code Playgroud)
我期待看到这个:
vmovupd ymm0,XMMWORD PTR [rsi+rax*1]
Run Code Online (Sandbox Code Playgroud)
并充分利用256位寄存器(YMM0),而不是它看起来像海湾合作委员会已决定在128位部分(填写XMM0),然后再次加载另一半vinsertf128.
有人能够解释这个吗?在MSVC VS 2012中
使用单个vmovupd编译等效代码.
我运行gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0在Ubuntu的18.04 X86-64.
请考虑以下最小示例minimal.cpp(https://godbolt.org/z/x7dYes91M)。
#include <immintrin.h>
#include <algorithm>
#include <ctime>
#include <iostream>
#include <numeric>
#include <vector>
#define NUMBER_OF_TUPLES 134'217'728UL
void transform(std::vector<int64_t>* input, std::vector<double>* output, size_t batch_size) {
for (size_t startOfBatch = 0; startOfBatch < NUMBER_OF_TUPLES; startOfBatch += batch_size) {
size_t endOfBatch = std::min(startOfBatch + batch_size, NUMBER_OF_TUPLES);
for (size_t idx = startOfBatch; idx < endOfBatch;) {
if (endOfBatch - idx >= 8) {
auto _loaded = _mm512_loadu_epi64(&(*input)[idx]);
auto _converted = _mm512_cvtepu64_pd(_loaded);
_mm512_storeu_epi64(&(*output)[idx], _converted);
idx += 8;
} else {
(*output)[idx] …Run Code Online (Sandbox Code Playgroud) 我对C ++内存管理非常陌生,但想让我不厌其烦地构建一个简单的分配器,该分配器可以预先为某些容器预先分配足够的内存。
我看过Alexandrescu Loki图书馆并尝试阅读一些博客,但是所有这些只是让我难以理解。我想从一些原始且可行的起点入手,对其进行扩展,然后看它如何演变。这就是我现在所拥有的以及我真正理解的(我的出发点):
template <class T>
struct Allocator {
Allocator(){};
template <class U>
Allocator(Allocator<U> const&);
T* allocate(size_t s) {
return static_cast<T*>(::operator new(s * sizeof(T)));
}
void deallocate(T* p, size_t s) {
::operator delete(p);
}
void construct(T* p, T const& val) {
::new((void *)p) T(val);
}
void destroy(T* p) {
return ((T *) p)->~T();
}
using value_type = T;
};
Run Code Online (Sandbox Code Playgroud)
因此,我现在可以像这样使用它:
std::vector<int, Allocator<int> > vec;
Run Code Online (Sandbox Code Playgroud)
这个分配器非常简单,我理解它的作用。现在,我想对其进行一点扩展,以便我的客户端代码如下所示:
std::vector<int, Allocator<int, 8> > vec;
Run Code Online (Sandbox Code Playgroud)
现在,我希望代码为8个元素分配足够的内存。我尝试使用以下几行扩展我的起始代码:
template <class T, size_t T_num_els>
struct Allocator { …Run Code Online (Sandbox Code Playgroud)