首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测量C++代码的CPU周期

测量C++代码的CPU周期
EN

Stack Overflow用户
提问于 2015-05-12 16:38:02
回答 1查看 3.7K关注 0票数 2

我的目标是使用简单的代码来度量(不同的)缓存的效果。我跟随这篇文章,特别是第20和21页:https://people.freebsd.org/~lstewart/articles/cpumemory.pdf

我正在开发一个64位的linux。L1d缓存为32K,L2为256 K,L3为25M。

这是我的代码(我使用没有标志的g++编译这段代码):

代码语言:javascript
复制
#include <iostream>

// ***********************************
// This is for measuring CPU clocks
#if defined(__i386__)
static __inline__ unsigned long long rdtsc(void)
{
    unsigned long long int x;
    __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
    return x;
}
#elif defined(__x86_64__)
static __inline__ unsigned long long rdtsc(void)
{
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#endif
// ***********************************


static const int ARRAY_SIZE = 100;

struct MyStruct {
    struct MyStruct *n;
};

int main() {
    MyStruct myS[ARRAY_SIZE];
    unsigned long long cpu_checkpoint_start, cpu_checkpoint_finish;

    //  Initializing the array of structs, each element pointing to the next 
    for (int i=0; i < ARRAY_SIZE - 1; i++){
        myS[i].n = &myS[i + 1];
        for (int j = 0; j < NPAD; j++)
            myS[i].pad[j] = (long int) i;
    }
    myS[ARRAY_SIZE - 1].n = NULL;   // the last one
    for (int j = 0; j < NPAD; j++)
        myS[ARRAY_SIZE - 1].pad[j] = (long int) (ARRAY_SIZE - 1);

    // Filling the cache
    MyStruct *current = &myS[0];
    while ((current = current->n) != NULL)
        ;

    // Sequential access
    current = &myS[0];

    // For CPU usage in terms of clocks (ticks)
    cpu_start = rdtsc();

    while ((current = current->n) != NULL)
        ;

    cpu_finish = rdtsc();

    unsigned long long avg_cpu_clocks = (cpu_finish - cpu_start) / ARRAY_SIZE;

    std::cout << "Avg CPU Clocks:   " << avg_cpu_clocks << std::endl;
    return 0;
}

我有两个问题:

1-我的ARRAY_SIZE从1到1,000,000 (所以我的数组的大小在2B到2MB之间),但是平均CPU时钟总是10。

根据这一PDF格式(图3-10在第21页),当数组完全符合L1时,我会期望得到3-5个时钟,当它超过L1的大小时,会得到更高的数字(9个周期)。

2-如果我将ARRAY_SIZE增加超过1,000,000,我将得到分割错误(内核转储),这是由于堆栈溢出。我的问题是,使用动态分配(MyStruct *myS = new MyStruct[ARRAY_SIZE])是否不会导致任何性能损失。

EN

回答 1

Stack Overflow用户

发布于 2015-05-12 23:17:05

这是我的代码(我用没有标志的g++编译这段代码)

如果您不传递-O3,那么while ((current = current->n) != NULL)将被编译成多个内存访问,而不是一个加载指令。通过传递-O3,循环将被编译成:

代码语言:javascript
复制
.L3:
mov     rax, QWORD PTR [rax]
test    rax, rax
jne     .L3

正如您所期望的那样,这将在每次迭代中运行4个周期。

请注意,您可以使用__rdtsc编译器内部而不是内联程序集。见:Get CPU cycle count?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30196766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档