相关疑难解决方法(0)

每个程序员应该了解的内存?

我想知道Ulrich Drepper 从2007年开始对每个程序员应该知道的内容有多少仍然有效.另外,我找不到比1.0更新的版本或勘误表.

optimization x86 memory-management cpu-architecture micro-optimization

145
推荐指数
3
解决办法
2万
查看次数

如何在多核Intel CPU中共享高速缓存?

关于多核CPU或多处理器系统中使用的高速缓存存储器,我有几个问题.(虽然与编程没有直接关系,但是当一个人为多核处理器/多处理器系统编写软件时会产生很多反响,因此在这里问!)

  1. 在多处理器系统或多核处理器(Intel Quad Core,Core two Duo等......)中,每个cpu核心/处理器都有自己的缓存(数据和程序缓存)吗?

  2. 一个处理器/核心可以访问彼此的高速缓存,因为如果允许它们访问彼此的高速缓存,那么我认为可能存在较少的高速缓存未命中,如果特定处理器高速缓存没有一些数据但是其他一些处理器的缓存可能有它,从而避免从内存读入第一个处理器的缓存?这个假设是否有效且真实?

  3. 允许任何处理器访问其他处理器的高速缓冲存储器会有任何问题吗?

performance x86 intel multiprocessing cpu-cache

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

29
推荐指数
3
解决办法
2万
查看次数

涉及Intel SnB系列CPU上的微编码指令的循环分支对齐

这与此问题有关,但不一样:x86-64汇编的性能优化 - 对齐和分支预测与我之前的问题略有关系:无符号64位到双倍转换:为什么这个算法来自g ++

以下是一个不真实的测试用例.这种素性测试算法是不明智的.我怀疑任何真实世界的算法都不会执行如此多的小内循环(num大概是2**50的大小).在C++ 11中:

using nt = unsigned long long;
bool is_prime_float(nt num)
{
   for (nt n=2; n<=sqrt(num); ++n) {
      if ( (num%n)==0 ) { return false; }
   }
   return true;
}
Run Code Online (Sandbox Code Playgroud)

然后g++ -std=c++11 -O3 -S生成以下内容,包含RCX n和包含XMM6 sqrt(num).请参阅我之前发布的剩余代码(在此示例中从未执行过,因为RCX永远不会变得足够大,不能被视为带符号的否定).

jmp .L20
.p2align 4,,10
.L37:
pxor    %xmm0, %xmm0
cvtsi2sdq   %rcx, %xmm0
ucomisd %xmm0, %xmm6
jb  .L36   // Exit the loop
.L20:
xorl    %edx, %edx
movq    %rbx, %rax …
Run Code Online (Sandbox Code Playgroud)

performance x86 assembly intel micro-optimization

21
推荐指数
3
解决办法
2156
查看次数

内存屏障是否确保缓存一致性已完成?

假设我有两个线程来操纵全局变量x.每个线程(或我认为的每个核心)都有一个缓存副本x.

现在说Thread A执行以下说明:

set x to 5
some other instruction
Run Code Online (Sandbox Code Playgroud)

现在set x to 5执行时,缓存的值x将设置为5,这将导致缓存一致性协议使用新值来操作和更新其他核心的缓存x.

现在我的问题是:什么时候x实际设置5在Thread A缓存中,其他内核的缓存在some other instruction执行之前是否会更新?或者应该使用内存屏障来确保?:

set x to 5
memory barrier
some other instruction
Run Code Online (Sandbox Code Playgroud)

注意:假设指令是按顺序执行的,也假设set x to 5执行时,5会立即放入线程A的缓存中(因此指令不会放在队列中或稍后要执行的内容).

x86 assembly operating-system memory-barriers cpu-cache

16
推荐指数
2
解决办法
1513
查看次数

CPU缓存如何影响C程序的性能

我试图更多地了解 CPU 缓存如何影响性能。作为一个简单的测试,我将矩阵第一列的值与不同数量的总列数相加。

// compiled with: gcc -Wall -Wextra -Ofast -march=native cache.c
// tested with: for n in {1..100}; do ./a.out $n; done | tee out.csv
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

double sum_column(uint64_t ni, uint64_t nj, double const data[ni][nj])
{
    double sum = 0.0;
    for (uint64_t i = 0; i < ni; ++i) {
        sum += data[i][0];
    }
    return sum;
}

int compare(void const* _a, void const* _b)
{
    double const a = *((double*)_a);
    double …
Run Code Online (Sandbox Code Playgroud)

c performance cpu-cache

16
推荐指数
1
解决办法
1144
查看次数

为什么Skylake比Broadwell-E在单线程内存吞吐量方面要好得多?

我们有一个简单的内存吞吐量基准.对于大块内存,它所做的只是重复记忆.

在几台不同的机器上查看结果(针对64位编译),Skylake机器的性能明显优于Broadwell-E,保持OS(Win10-64),处理器速度和RAM速度(DDR4-2133)不变.我们不是说几个百分点,而是大约2个因素.Skylake配置为双通道,Broadwell-E的结果不会因双/三/四通道而异.

任何想法为什么会这样?随后的代码在VS2015的Release中编译,并报告完成每个memcpy的平均时间:

64位:Skylake为2.2ms,Broadwell-E为4.5ms

32位:Skylake为2.2ms,Broadwell-E为3.5ms.

通过利用多个线程,我们可以在四通道Broadwell-E构建上获得更大的内存吞吐量,这很不错,但是看到单线程内存访问的这种巨大差异令人沮丧.为什么差异如此显着的任何想法?

我们还使用了各种基准测试软件,他们验证了这个简单示例所展示的内容 - 单线程内存吞吐量在Skylake上更好.

#include <memory>
#include <Windows.h>
#include <iostream>

//Prevent the memcpy from being optimized out of the for loop
_declspec(noinline) void MemoryCopy(void *destinationMemoryBlock, void *sourceMemoryBlock, size_t size)
{
    memcpy(destinationMemoryBlock, sourceMemoryBlock, size);
}

int main()
{
    const int SIZE_OF_BLOCKS = 25000000;
    const int NUMBER_ITERATIONS = 100;
    void* sourceMemoryBlock = malloc(SIZE_OF_BLOCKS);
    void* destinationMemoryBlock = malloc(SIZE_OF_BLOCKS);
    LARGE_INTEGER Frequency;
    QueryPerformanceFrequency(&Frequency);
    while (true)
    {
        LONGLONG total = 0;
        LONGLONG max = 0;
        LARGE_INTEGER StartingTime, …
Run Code Online (Sandbox Code Playgroud)

performance benchmarking x86 intel cpu-architecture

12
推荐指数
1
解决办法
1594
查看次数

For循环效率:合并循环

我一直有这个想法,减少迭代次数是的方式来使程序更加高效.由于我从未真正确认过,我开始测试这个.

我制作了以下C++程序来测量两个不同函数的时间:

  • 第一个函数执行单个大循环并使用一组变量.
  • 第二个函数执行多个同样大的循环,但每个变量只有一个循环.

完整的测试代码:

    #include <iostream>
    #include <chrono>

    using namespace std;

    int* list1; int* list2;
    int* list3; int* list4;
    int* list5; int* list6;
    int* list7; int* list8;
    int* list9; int* list10;

    const int n = 1e7;

    // **************************************
    void myFunc1()
    {
        for (int i = 0; i < n; i++)
        {
            list1[i] = 2;
            list2[i] = 4;
            list3[i] = 8;
            list4[i] = 16;
            list5[i] = 32;
            list6[i] = 64;
            list7[i] = 128;
            list8[i] = 256;
            list9[i] = …
Run Code Online (Sandbox Code Playgroud)

c++ performance benchmarking loops

7
推荐指数
2
解决办法
851
查看次数

不同级别缓存(即 L1、L2 和 L3)之间的缓存一致性(MESI 协议)

这是关于跨不同层的缓存一致性协议cache。我的理解(X86_64)L1是,它由一个核心独占,L2介于两个核心之间,并且L3适用于一个CPU插槽中的所有核心。我已经阅读了MESI协议功能,关于存储缓冲区、无效队列、无效消息等。我的疑问是,它仅MESI适用于L1还是适用于L2并且L3也适用。L2或者 for和之间是否有不同的缓存同步L3。

caching x86-64 cpu-architecture cpu-cache mesi

6
推荐指数
1
解决办法
1229
查看次数

英特尔CPU缓存策略

我有一台带有2.50GHz处理器的Intel®Core™i5-2450M CPU的笔记本电脑。我在Ubuntu 12.04(x86_64)上,尝试查找有关我的处理器的信息。

我能够找到我一直在寻找的大多数信息

cat /proc/cpuinfo
Run Code Online (Sandbox Code Playgroud)

和

lscpu
Run Code Online (Sandbox Code Playgroud)

我还想找出在每个缓存级别上使用的缓存策略。是回写还是透写?

有什么工具可以用来查找此类信息?

提前致谢。

linux cpu policy caching

5
推荐指数
2
解决办法
4321
查看次数