c - 为什么在跨步预取时循环顺序很重要?

标签 c caching prefetch

在 C 中,您被告知以行优先顺序遍历矩阵,因为这就是数组在引擎盖下的存储方式,行优先迭代利用整个缓存行,从而减少缓存未命中。事实上,我确实在我的机器上看到了行优先和列优先迭代之间的巨大性能差异。测试代码:

#include <stdio.h>
#include <stdlib.h>

#include <time.h>
#include <sys/resource.h>

int getTime()
{
  struct timespec tsi;

  clock_gettime(CLOCK_MONOTONIC, &tsi);
  double elaps_s = tsi.tv_sec;
  long elaps_ns = tsi.tv_nsec;
  return (int) ((elaps_s + ((double)elaps_ns) / 1.0e9) * 1.0e3);
}

#define N 1000000
#define M 100

void main()
{
  int *src = malloc(sizeof(int) * N * M);
  int **arr = malloc(sizeof(int*) * N);
  for(int i = 0; i < N; ++i)
    arr[i] = &src[i * M];

  for(int i = 0; i < N; ++i)
    for(int j = 0; j < M; ++j)
      arr[i][j] = 1;

  int total = 0;

  int pre = getTime();


  for(int j = 0; j < M; ++j)
    for(int i = 0; i < N; ++i)
      total += arr[i][j];

  /*
  for(int i = 0; i < N; ++i)
    for(int j = 0; j < M; ++j)
      total += arr[i][j];
  */

  int post = getTime();

  printf("Result: %d, took: %d ms\n", total, post - pre);
}

但是,现代内存系统具有预取器,可以预测跨步访问,并且当您遍历列时,您将遵循非常规则的模式。这难道不应该让列优先迭代的执行类似于行优先迭代吗?

最佳答案

缓存行具有一定的大小(例如 64 字节),处理器读取和写入完整的缓存行。比较处理的字节数和读取和写入的字节数。

关于c - 为什么在跨步预取时循环顺序很重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38057642/

相关文章:

caching - Aerospike 为特定字段设置到期日期

python - Django 无法在模板中迭代 prefetch_lated 对象

performance - 预取指令是否需要在退出之前返回其结果?

c++ - 如何修复艺术ascii,我点击一个字母没问题,但输入一个阶段艺术结果错误

laravel - 使用 Redis 在 Laravel 中缓存

c - 在Kali Linux中运行时出现段错误-客户端和服务器聊天室

c - 使用自修改代码观察 x86 上的陈旧指令提取

html - 预取或预加载 Typekit 字体

c - 如何根据传递的结构名称部分访问结构

c - FOTA : How can i do firmware update over the air?