如何实现缓存å‹å¥½çš„动æ€äºŒå‰æ ‘?

时间:2017-01-27 22:21:33

标签: c++ memory-management data-structures binary-tree cpu-cache

æ ¹æ®åŒ…括Wikipedia在内的多个æ¥æºï¼Œå®žçŽ°äºŒå‰æ ‘的两ç§æœ€å¸¸ç”¨çš„方法是:

  1. 节点和指针(或引用)其中æ¯ä¸ªèŠ‚点显å¼ä¿å­˜å…¶å­èŠ‚点。
  2. 数组,其å­èŠ‚点的ä½ç½®ç”±å…¶çˆ¶èŠ‚点的索引éšå¼ã€‚
  3. 第二个在内存使用和引用ä½ç½®æ–¹é¢æ˜Žæ˜¾ä¼˜è¶Šã€‚但是,如果您希望å…许树中的æ’入和删除,å¯èƒ½ä¼šä½¿æ ‘ä¸å¹³è¡¡ï¼Œåˆ™ä¼šå¯¼è‡´é—®é¢˜ã€‚这是因为此设计的内存使用é‡æ˜¯æ ‘深度的指数函数。

    å‡è®¾æ‚¨è¦æ”¯æŒæ­¤ç±»æ’入和删除。如何实现树,以便树é历å¯ä»¥å……分利用CPU缓存。

    我正在考虑为节点创建一个对象池并将它们分é…到一个数组中。这样节点将é è¿‘在一起 - >因此,良好的å‚考地点。

    但是,如果节点的大å°ä¸Žç¼“存行的大å°ç›¸åŒï¼Œè¿™æ˜¯å¦æœ‰æ„义?

    如果您的L1行大å°ä¸º64字节,并且您访问std::vector<std::uint8_t>(64)的第一个æˆå‘˜ï¼Œåˆ™å¯èƒ½åœ¨L1缓存中拥有该å‘é‡çš„全部内容。这æ„味ç€æ‚¨å¯ä»¥éžå¸¸å¿«é€Ÿåœ°è®¿é—®ä»»ä½•å…ƒç´ ã€‚但是如果元素的大å°ä¸Žç¼“存行大å°ç›¸åŒæ€Žä¹ˆåŠžï¼Ÿç”±äºŽL1,L2å’ŒL3缓存的缓存行为likely not to be very different,因此似乎没有办法在哪个ä½ç½®å¼•ç”¨å¯ä»¥æ供帮助。我错了å—?还有什么å¯ä»¥åšçš„?

2 个答案:

答案 0 :(得分:4)

除éžæ‚¨æ­£åœ¨ç ”究如何改进缓存访问模å¼çš„二å‰æ ‘,å¦åˆ™æˆ‘觉得这是XY problem - 您è¦è§£å†³çš„问题是什么?为什么您认为二å‰æ ‘是解决问题的最佳算法?什么是预期的工作集大å°ï¼Ÿ

如果您正在寻找一个通用的关è”存储,那么有多个缓存å‹å¥½ï¼ˆå…¶ä»–关键字:“缓存高效â€ï¼Œâ€œç¼“存无关â€ï¼‰ç®—法,例如Judy arrays,其中有一个extensive explanation PDF

如果您的工作集大å°è¶³å¤Ÿå°ï¼Œå¹¶ä¸”您åªéœ€è¦æœ‰åºçš„一组项目,那么一个简å•çš„有åºæ•°ç»„就足够了,这å¯èƒ½ä¼šå¸¦æ¥å¦ä¸€ä¸ªæ€§èƒ½ä¼˜åŠ¿ - branch prediction。

最åŽï¼Œæ‰¾å‡ºæœ€é€‚åˆæ‚¨ç”¨ä¾‹çš„方法是å°è¯•è¡¡é‡ä¸åŒçš„方法。

答案 1 :(得分:1)

使用å—分é…器。

您有一个或几个连续的内存“池â€ï¼Œæ‚¨å¯ä»¥ä»Žä¸­é‡Šæ”¾å›ºå®šå¤§å°çš„å—。它是作为链表实现的。所以分é…就是

answer = head, 
head = head->next, 
return answer; 

å…è´¹åªæ˜¯

tofree->next = head;
head = tofree;

如果您å…许多个池当然需è¦ç¼–写代ç æ¥ç¡®å®šæ± ï¼Œè¿™ä¼šå¢žåŠ ä¸€äº›å¤æ‚性,但ä¸ä¼šå¤ªå¤šã€‚它本质上是一个简å•çš„内存分é…系统。 由于所有池æˆå‘˜åœ¨å†…存中都很é è¿‘,因此您å¯ä»¥åœ¨å°æ ‘上获得良好的缓存一致性。对于大树,你必须è¦æœ‰ç‚¹èªæ˜Žã€‚