Nat*_*ate 8 memory cpu performance caching
很明显,没有明确的方法或某些系统调用可以帮助程序员将变量放入CPU缓存中.
但我认为某种编程风格或设计良好的算法可以增加变量可以缓存到CPU缓存中的可能性.
这是我的例子:
我想在一个数组的末尾添加一个8字节结构,该数组由在全局主存储器区域中声明的相同类型的结构组成.
这个过程不断重复进行400万次操作.此过程需要6秒,每次操作需要1.5 us.我认为这个结果表明两个内存区域还没有被缓存.
我从缓存无关的算法中得到了一些线索,所以我尝试了几种方法来增强它.到现在为止,还没有增强.
我认为一些聪明的代码可以减少经过的时间,最多可以减少10到100倍.请告诉我方式.
-------------------------------------------------------------------------
附加(2011-04-01)
达蒙〜谢谢你的评论!
阅读完评论后,我再次分析了我的代码,发现了一些我错过的内容.我附加的以下代码是我原始代码的缩写版本.
为了准确测量每个操作的执行时间(在原始代码中,有几种不同类型的操作),我使用clock_gettime()函数插入了时间测量代码.我想如果我测量每个操作的执行时间并累积它们,可以避免主循环的额外成本.
在原始代码中,时间测量代码被宏功能隐藏,所以我完全忘了它.
这段代码的运行时间差不多是6秒.但是如果我摆脱主循环中的时间测量功能,它将变为0.1秒.
由于该clock_gettime()函数支持非常高的精度(高达1纳秒),在独立线程的基础上执行,并且它需要非常大的结构,我认为该函数导致缓存输出连续插入的主存储区域执行.
再次感谢您的评论.为了进一步增强,任何建议对我优化代码都非常有帮助.
我认为分层定义的结构变量可能会导致不必要的时间成本,但首先我想知道它会有多少,然后再将其更改为更多C风格的代码.
typedef struct t_ptr {
    uint32 isleaf :1, isNextLeaf :1, ptr :30;
    t_ptr(void) {
        isleaf = false;
        isNextLeaf = false;
        ptr = NIL;
    }
} PTR;
typedef struct t_key {
    uint32 op :1, key :31;
    t_key(void) {
        op = OP_INS;
        key = 0;
    }
} KEY;
typedef struct t_key_pair {
    KEY key;
    PTR ptr;
    t_key_pair() {
    }
    t_key_pair(KEY k, PTR p) {
        key = k;
        ptr = p;
    }
} KeyPair;
typedef struct t_op {
    KeyPair keyPair;
    uint seq;
    t_op() {
        seq = 0;
    }
} OP;
#define MAX_OP_LEN 4000000
typedef struct t_opq {
    OP ops[MAX_OP_LEN];
    int freeOffset;
    int globalSeq;
    bool queueOp(register KeyPair keyPair);
} OpQueue;
bool OpQueue::queueOp(register KeyPair keyPair) {
    bool isFull = false;
    if (freeOffset == (int) (MAX_OP_LEN - 1)) {
        isFull = true;
    }
    ops[freeOffset].keyPair = keyPair;
    ops[freeOffset].seq = globalSeq++;
    freeOffset++;
}
OpQueue opQueue;
#include <sys/time.h>
int main() {
    struct timespec startTime, endTime, totalTime;
    for(int i = 0; i < 4000000; i++) {
        clock_gettime(CLOCK_REALTIME, &startTime);
        opQueue.queueOp(KeyPair());
        clock_gettime(CLOCK_REALTIME, &endTime);
        totalTime.tv_sec += (endTime.tv_sec - startTime.tv_sec);
        totalTime.tv_nsec += (endTime.tv_nsec - startTime.tv_nsec);
    }
    printf("\n elapsed time: %ld", totalTime.tv_sec * 1000000LL + totalTime.tv_nsec / 1000L);
}
我一直无法强制缓存,但您可以强制内存不可缓存。如果您有大型其他数据结构,您可能会排除这些数据结构,以免它们污染您的缓存。这可以通过为 Windows VirutalAllocXXX 函数指定 PAGE_NOCACHE 来完成。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
| 归档时间: | 
 | 
| 查看次数: | 587 次 | 
| 最近记录: |