我对编写一个memcpy()教育练习感兴趣.我不会写一篇关于我做了什么和没想过的论文,但这里
有一些人的实现:
__forceinline // Since Size is usually known,
// most useless code will be optimized out
// if the function is inlined.
void* myMemcpy(char* Dst, const char* Src, size_t Size)
{
void* start = Dst;
for ( ; Size >= sizeof(__m256i); Size -= sizeof(__m256i) )
{
__m256i ymm = _mm256_loadu_si256(((const __m256i* &)Src)++);
_mm256_storeu_si256(((__m256i* &)Dst)++, ymm);
}
#define CPY_1B *((uint8_t * &)Dst)++ = *((const uint8_t * &)Src)++
#define CPY_2B *((uint16_t* &)Dst)++ = *((const uint16_t* &)Src)++
#define CPY_4B …Run Code Online (Sandbox Code Playgroud) 我有类似的东西:
if (f = acquire_load() == ) {
... use Foo
}
Run Code Online (Sandbox Code Playgroud)
和:
auto f = new Foo();
release_store(f)
Run Code Online (Sandbox Code Playgroud)
您可以很容易地想象使用atomic with load(memory_order_acquire)和store(memory_order_release)的acquire_load和release_store的实现.但是现在如果release_store是用_mm_stream_si64实现的,这是一个非临时写入,而不是针对x64上的其他商店进行排序的?如何获得相同的语义?
我认为以下是最低要求:
atomic<Foo*> gFoo;
Foo* acquire_load() {
return gFoo.load(memory_order_relaxed);
}
void release_store(Foo* f) {
_mm_stream_si64(*(Foo**)&gFoo, f);
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
// thread 1
if (f = acquire_load() == ) {
_mm_lfence();
... use Foo
}
Run Code Online (Sandbox Code Playgroud)
和:
// thread 2
auto f = new Foo();
_mm_sfence(); // ensures Foo is constructed by the time f is published to gFoo
release_store(f)
Run Code Online (Sandbox Code Playgroud)
那是对的吗?我非常肯定这里绝对需要sfence.但是那个lfence怎么样?是否需要或者简单的编译器障碍对于x64是否足够?例如asm volatile("":::"memory").根据x86内存模型,负载不会与其他负载重新排序.所以根据我的理解,只要存在编译器障碍,acquire_load()必须在if语句中的任何加载之前发生.
当从连续的内存位置执行一系列_mm_stream_load_si128()调用(MOVNTDQA)时,硬件预取器是否仍会启动,或者我应该使用显式软件预取(使用NTA提示)以获得预取的好处,同时仍然避免缓存污染?
我问这个的原因是因为他们的目标似乎与我相矛盾.流加载将获取绕过缓存的数据,而预取器尝试主动将数据提取到缓存中.
当顺序迭代一个大型数据结构(处理过的数据不会在很长一段时间内被修饰)时,我有必要避免污染chache层次结构,但我不想因频繁出现频繁的~100次循环处罚-fetcher闲置.
目标架构是Intel SandyBridge
假设我有一个用c ++编写的函数,它在很多向量上执行矩阵向量乘法.它需要一个指向要转换的向量数组的指针.我是否正确假设编译器无法有效地优化SIMD指令,因为它在编译时不知道传递指针的对齐(SSE需要16字节对齐或AVX需要32字节对齐)?或者数据的内存对齐与最佳SIMD代码无关,数据对齐只会影响缓存性能?
如果对齐对于生成的代码很重要,我怎么能让(visual c ++)编译器知道我打算只传递具有特定对齐值的函数?
avx ×2
simd ×2
sse ×2
x86 ×2
c ×1
c++ ×1
cpu-cache ×1
lock-free ×1
optimization ×1
performance ×1
prefetch ×1
stdatomic ×1
visual-c++ ×1
x86-64 ×1