Tag: 预取

读取或写入的预取之间的区别

gcc文档讨论了读取的预取和写入的预取之间的区别。 有什么技术差异?

通过延迟/性能测量确定NUMA布局

最近我一直在观察内存密集型工作负载中的性能影响,我无法解释。 试图找到底部我开始运行几个微基准测试,以确定常见的性能参数,如缓存行大小和L1 / L2 / L3缓存大小(我已经知道了,我只是想看看我的测量是否反映了实际值)。 对于缓存行测试,我的代码大致如下(Linux C,但这个概念当然与Windows等相似): char *array = malloc (ARRAY_SIZE); int count = ARRAY_SIZE / STEP; clock_gettime(CLOCK_REALTIME, &start_time); for (int i = 0; i < ARRAY_SIZE; i += STEP) { array[i]++; } clock_gettime(CLOCK_REALTIME, &end_time); // calculate time per element here: [..] 从1到128改变STEP表明从STEP=64开始,我看到每个元素的时间没有进一步增加,即每次迭代都需要获取一个主导运行时的新缓存行。 改变ARRAY_SIZE从1K到16384K保持STEP=64我能够创建一个很好的绘图,展示一个大致对应于L1,L2和L3延迟的步骤模式。 为了获得可靠的数字,有必要多次重复for循环,对于非常小的arrays大小甚至100,000次。 然后,在我的IvyBridge笔记本上,我可以清楚地看到L1结束于64K,L2处于256K,甚至L3处于6M。 现在谈谈我的真正问题:在NUMA系统中,任何一个核心都将获得远程主内存甚至共享缓存,这些缓存不一定与其本地缓存和内存一样接近。 我希望看到延迟/性能的差异,从而确定在保持快速缓存/部分内存时我可以分配多少内存。 为此,我改进了我的测试,以1/10 MB块的forms遍历内存,分别测量延迟,然后收集最快的块,大致如下: for (int chunk_start […]

当程序将受益于预取和非临时加载/存储?

我做了一个测试 for (i32 i = 0; i < 0x800000; ++i) { // Hopefully this can disable hardware prefetch i32 k = (i * 997 & 0x7FFFFF) * 0x40; _mm_prefetch(data + ((i + 1) * 997 & 0x7FFFFF) * 0x40, _MM_HINT_NTA); for (i32 j = 0; j < 0x40; j += 0x10) { //__m128 v = […]

为什么GCC __builtin_prefetch不能提高性能?

我正在编写一个程序来分析社交网络图。 这意味着程序需要大量的随机内存访问。 在我看来,预取应该有所帮助。 这是从顶点的邻居读取值的一小段代码。 for (size_t i = 0; i < v.get_num_edges(); i++) { unsigned int id = v.neighbors[i]; res += neigh_vals[id]; } 我将上面的代码转换为下面的代码,并预取顶点的邻居值。 int *neigh_vals = new int[num_vertices]; for (size_t i = 0; i < v.get_num_edges(); i += 128) { size_t this_end = std::min(v.get_num_edges(), i + 128); for (size_t j = i; j < […]