很明显,没有明确的方式或某些系统调用 帮助程序员将变量放入CPU缓存中。
但我认为某种编程风格或精心设计 算法可以增加可能性 变量可以缓存到CPU缓存中。
以下是我的例子:
我想在数组的末尾添加一个8字节结构 在全局主存中声明的相同类型结构 区域。
此过程不断重复进行400万次操作。此过程需要6秒,每次操作需要1.5 us。我认为这个结果表明两个内存区域尚未缓存。
我从cache-oblivious algorithm得到了一些线索,所以我尝了几个 提高这一点的方法。到现在为止,还没有增强。
我认为一些聪明的代码可以减少经过的时间,最多可达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);
}
答案 0 :(得分:3)
您不会将结构放入任何缓存中。 CPU会自动为您执行此操作。 CPU比那更聪明;如果您访问顺序内存,它将开始将内存中的内容放入缓存,然后再读取它们。
实际上,对于像这样的简单代码,你应该花费在测量上的时间是执行代码的时间的十倍(在你的情况下显然是60倍)。
因为你对clock_gettime()充满信心:我建议你连续五次调用它并存储结果,然后打印差异。有分辨率,有精确度,而且返回当前时间需要多长时间,这是非常长的。
答案 1 :(得分:2)
我无法强制缓存,但您可以强制内存不可缓存。如果您有其他大型数据结构,则可以排除这些数据结构,这样它们就不会污染您的缓存。这可以通过为Windows VirutalAllocXXX函数指定PAGE_NOCACHE来完成。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx