Nat*_*ate 8 memory cpu performance caching
很明显,没有明确的方法或某些系统调用可以帮助程序员将变量放入CPU缓存中.
但我认为某种编程风格或设计良好的算法可以增加变量可以缓存到CPU缓存中的可能性.
这是我的例子:
我想在一个数组的末尾添加一个8字节结构,该数组由在全局主存储器区域中声明的相同类型的结构组成.
这个过程不断重复进行400万次操作.此过程需要6秒,每次操作需要1.5 us.我认为这个结果表明两个内存区域还没有被缓存.
我从缓存无关的算法中得到了一些线索,所以我尝试了几种方法来增强它.到现在为止,还没有增强.
我认为一些聪明的代码可以减少经过的时间,最多可以减少10到100倍.请告诉我方式.
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
附加(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);
}
Run Code Online (Sandbox Code Playgroud)
我一直无法强制缓存,但您可以强制内存不可缓存。如果您有大型其他数据结构,您可能会排除这些数据结构,以免它们污染您的缓存。这可以通过为 Windows VirutalAllocXXX 函数指定 PAGE_NOCACHE 来完成。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
| 归档时间: |
|
| 查看次数: |
587 次 |
| 最近记录: |