相关疑难解决方法(0)

为memcpy增强了REP MOVSB

我想使用增强的REP MOVSB(ERMSB)为自定义获得高带宽memcpy.

ERMSB引入了Ivy Bridge微体系结构.如果您不知道ERMSB是什么,请参阅英特尔优化手册中的"增强型REP MOVSB和STOSB操作(ERMSB)" 部分.

我知道直接执行此操作的唯一方法是使用内联汇编.我从https://groups.google.com/forum/#!topic/gnu.gcc.help/-Bmlm_EG_fE获得了以下功能

static inline void *__movsb(void *d, const void *s, size_t n) {
  asm volatile ("rep movsb"
                : "=D" (d),
                  "=S" (s),
                  "=c" (n)
                : "0" (d),
                  "1" (s),
                  "2" (n)
                : "memory");
  return d;
}
Run Code Online (Sandbox Code Playgroud)

然而,当我使用它时,带宽远小于memcpy. 使用我的i7-6700HQ(Skylake)系统,Ubuntu 16.10,DDR4 @ 2400 MHz双通道32 GB,GCC 6.2,__movsb获得15 GB/s并memcpy获得26 GB/s.

为什么带宽如此低REP MOVSB?我该怎么做才能改善它?

这是我用来测试它的代码.

//gcc -O3 -march=native -fopenmp foo.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly gcc memcpy

56
推荐指数
4
解决办法
1万
查看次数

malloc实现是否会将free-ed内存返回给系统?

我有一个长期存在的应用程序,频繁的内存分配 - 释放.任何malloc实现都会将释放的内存返回给系统吗?

在这方面,什么是以下行为:

  • ptmalloc 1,2(默认为glibc)或3
  • dlmalloc
  • tcmalloc(谷歌线程malloc)
  • solaris 10-11默认malloc和mtmalloc
  • FreeBSD 8默认malloc(jemalloc)
  • Hoard malloc?

更新

如果我有一个应用程序,其白天和夜晚的内存消耗可能非常不同(例如),我可以强制任何malloc将系统释放的内存吗?

如果没有这样的返回,释放的内存将被多次换出,但这样的内存只包含垃圾.

malloc free mmap glibc tcmalloc

54
推荐指数
4
解决办法
2万
查看次数

这个memcpy实现中缺少什么/次优?

我对编写一个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)

c optimization x86 simd avx

26
推荐指数
3
解决办法
4232
查看次数

REP做什么设置?

引用英特尔 ®64 和IA-32架构优化参考手册,§2.4.6"REP String Enhancement":

使用REP字符串的性能特征可归因于两个组件: 启动开销和数据传输吞吐量.

[...]

对于较大粒度数据传输的REP字符串,随着ECX值的增加,REP String的启动开销呈逐步增加:

  • 短串(ECX <= 12):REP MOVSW/MOVSD/MOVSQ的延迟约为20个周期,
  • 快速字符串(ECX> = 76:不包括REP MOVSB):处理器实现通过移动尽可能多的16字节数据来提供硬件优化.如果其中一个16字节数据传输跨越缓存行边界,则REP字符串延迟的延迟会有所不同:

    • 无拆分:延迟包括大约40个周期启动成本,每个64字节的数据增加4个周期,
    • 高速缓存拆分:延迟包括大约35个周期启动成本,每64个字节的数据增加6个周期.
  • 中间字符串长度:REP MOVSW/MOVSD/MOVSQ的延迟具有大约15个周期启动成本加上word/dword/qword中数据移动的每次迭代的一个周期.

(强调我的)

没有进一步提及这种启动成本.它是什么?它做了什么,为什么总是需要更多的时间?

optimization performance x86 assembly

13
推荐指数
2
解决办法
1615
查看次数

是什么特意将x86缓存行标记为脏 - 任何写入,或者是否需要显式更改?

这个问题专门针对现代x86-64缓存一致性架构 - 我很欣赏其他CPU的答案可能会有所不同.

如果我写入内存,MESI协议要求首先将缓存行读入缓存,然后在缓存中进行修改(将值写入缓存行,然后将其标记为脏).在较旧的写入微架构中,这将触发高速缓存行被刷新,在写回期间,被刷新的高速缓存行可能会延迟一段时间,并且一些写入组合可能在两种机制下发生(更可能是回写) .我知道这与访问相同缓存行数据的其他核心如何交互 - 缓存监听等.

我的问题是,如果商店恰好匹配缓存中已有的值,如果没有单个位被翻转,那么任何英特尔微架构都会注意到这一点并且将该行标记为脏,从而可能将该行标记为独占,以及在某些时候跟随的回写内存开销?

当我向更多的循环进行矢量化时,我的矢量化操作组合基元不会明确地检查值的变化,并且在CPU/ALU中这样做似乎很浪费,但我想知道底层缓存电路是否可以在没有显式编码的情况下完成(例如,商店微操作或缓存逻辑本身).由于跨多个内核的共享内存带宽变得更加成为资源瓶颈,这似乎是一种越来越有用的优化(例如,重复调整相同的内存缓冲区 - 如果它们已经存在,我们不会重新读取RAM中的值在缓存中,但强制写回相同的值似乎很浪费).回写缓存本身就是对这类问题的承认.

我可以礼貌地要求阻止"在理论上"或"它确实无关紧要"的答案 - 我知道记忆模型是如何工作的,我正在寻找的是关于如何写出相同价值的硬性事实(而不是避免一个商店)将影响内存总线的争用你可以安全地假设是一台运行多个工作负载的机器几乎总是受内存带宽限制.另一方面,解释为什么芯片不这样做的确切原因(我悲观地假设他们没有这样做)将具有启发性......

更新: 这里的预期线路上的一些答案https://softwareengineering.stackexchange.com/questions/302705/are-there-cpus-that-perform-this-possible-l1-cache-write-optimization但仍然很多推测"它必须很难,因为它没有完成",并说如何在主CPU核心中这样做会很昂贵(但我仍然想知道为什么它不能成为实际缓存逻辑本身的一部分).

x86 x86-64 cpu-architecture cpu-cache memory-bandwidth

8
推荐指数
3
解决办法
577
查看次数

malloc_trim(0) 发布 Thread Arenas 的 Fastbins?

在过去一周左右的时间里,我一直在调查应用程序中内存使用量随时间累积的问题。我把它缩小到复制一个的行

std::vector< std::vector< std::vector< std::map< uint, map< uint, std::bitset< N> > > > > >

在工作线程中(我意识到这是一种组织内存的荒谬方式)。工作线程会定期被销毁、重新创建,并在线程启动时复制该内存结构。被复制的原始数据通过主线程的引用传递给工作线程。

使用 malloc_stat 和 malloc_info,我可以看到当工作线程被销毁时,它使用的 arena/heap 将用于该结构的内存保留在其 fastbins 的空闲列表中。这是有道理的,因为有许多小于 64 字节的单独分配。

问题是,当工作线程被重新创建时,它会创建一个新的 arena/heap 而不是重用前一个,这样来自先前 arenas/heap 的 fastbins 永远不会被重用。最终,系统会在重用之前的堆/arena 来重用他们持有的 fastbin 之前耗尽内存。

有点意外,我发现在我的主线程中调用 malloc_trim(0),在加入工作线程后,会导致线程 arenas/heap 中的 fastbins 被释放。据我所知,这种行为没有记录。有人有解释吗?

这是我用来查看此行为的一些测试代码:

// includes
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>
#include <mcheck.h>
#include <malloc.h>
#include <map>
#include <bitset>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

// Number of bits per bitset.
const int sizeOfBitsets …
Run Code Online (Sandbox Code Playgroud)

c++ malloc multithreading glibc

5
推荐指数
1
解决办法
1588
查看次数

使用openmp + SIMD没有加速

我是Openmp的新手,现在尝试使用Openmp + SIMD内在函数来加速我的程序,但结果远非期望.

为了简化案例而不丢失太多重要信息,我写了一个简单的玩具示例:

#include <omp.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <sys/time.h>

#include "immintrin.h" // for SIMD intrinsics

int main() {
    int64_t size = 160000000;
    std::vector<int> src(size);

    // generating random src data
    for (int i = 0; i < size; ++i)
        src[i] = (rand() / (float)RAND_MAX) * size;

    // to store the final results, so size is the same as src
    std::vector<int> dst(size);

    // get pointers for vector load and store
    int * src_ptr = src.data();
    int * …
Run Code Online (Sandbox Code Playgroud)

c++ performance multithreading simd openmp

5
推荐指数
1
解决办法
718
查看次数

为什么我看到使用 REP MOVSB 的 RFO(读取所有权)请求比使用 vmovdqa 的请求多

结帐 Edit3

我得到了错误的结果,因为我在测量时没有包括这里讨论的预取触发事件。话虽如此,AFAIKrep movsb与临时存储相比,我只看到 RFO 请求减少,memcpy因为在加载时预取更好,而没有对存储进行预取。不是因为 RFO 请求针对完整缓存行存储进行了优化。这种有意义的,因为我们没有看到RFO请求优化掉了vmovdqa一个zmm寄存器,我们预计如果真的在那里为整个缓存线存储情况。话虽如此,存储上缺乏预取和非临时写入的缺乏使得很难看出如何rep movsb具有合理的性能。

编辑:RFO 可能来自rep movsb不同的请求vmovdqa,因为rep movsb它可能不请求数据,只需在独占状态下取行即可。对于有收银机的商店,情况也可能如此zmm。但是,我没有看到任何性能指标来测试这一点。有谁知道吗?

问题

  1. 为什么我没有看到RFO请求减少时,我使用rep movsbmemcpy作为相比,memcpy与实现的vmovdqa
  2. 为什么我看到越来越多的RFO请求时,我用rep movsbmemcpy作为相比,memcpy与实现vmovdqa

两个单独的问题,因为我相信我应该看到 RFO 请求减少了rep movsb,但如果不是这种情况,我是否也应该看到增加?

背景

CPU - Icelake: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz

我试图在使用不同的方法时测试 RFO 请求的数量,memcpy包括:

  • 时间商店 -> vmovdqa
  • 非临时存储 …

x86-64 intel cpu-architecture memcpy micro-optimization

5
推荐指数
0
解决办法
225
查看次数