将 X 索引的内存复制到 C 中单个数组中的多个位置的最佳方法是什么?
试图解决的问题是 CPU 模拟器的模拟内存。原始硬件具有这种类型的内存镜像,我正在尝试通过代码复制它。
假设你有一个数组:
int memory[100] = {0};
并且您有 10 个索引,这些索引在不同的位置进行镜像。例如,如果 memory[0]
发生变化,索引 0、10、20、30... 应更改为该值,或者如果 memory[3]
发生变化,则索引3, 13, 23, 33 应该是镜像。
同样,如果任何镜像位置发生变化,所有其他镜像位置都应反射(reflect)这一点,例如,如果索引 23 发生变化,则 3、13、23、33 等应反射(reflect)这一点。
另一个要求是指定镜像位置的起点和终点的方法。例如,索引 10-19 可以镜像到索引 30-39,然后再次镜像到 70-79,在镜像索引段之间留下未修改的空间。
如果这样的话,使用 memcpy 是否是实现此目的的最快/最有效的方法,或者某种迭代循环和指针数学是否会更好地提高效率?如何进行指针数学运算来计算要复制到的起始地址以及目标地址?保存内存数组中起始地址的指针数组是否是处理此问题的最佳方法?
可能是这样的(这可能不会编译它只是我的一个想法的伪代码):
#define NUMBER_OF_MIRRORS 3
#define LENGTH_OF_MIRRORS 10
int memory[100] = {0};
int *memory_mirror_starts[3] = {&memory[10], &memory[30], &memory[70]};
// When memory needs to be mirrored
for(int i = 0; i < NUMBER_OF_MIRRORS; i++) {
for(int n = 0; n < LENGTH_OF_MIRRORS; n++) {
memory_mirror_starts[i][n] = memory_mirror_starts[0][n];
}
}
我想我可能走在正确的轨道上,但这并不能满足我的所有要求,因为它专门将第一个镜像的结果复制到其余镜像。如果写入到任何其他镜像,它将被覆盖而不是复制到其他镜像。
感谢任何提示和建议。
最佳答案
指定每个镜像在 memory
中的起始位置数组,“指向‘内存’的指针数组有效”,
int *memory_mirror_starts[3] = {&memory[10], &memory[30], &memory[70]}; // (A)
或者您可以简单地给出每个偏移量:
int memory_mirror_starts[3] = { 10, 30, 70 }; // (B)
然后为了确保对给定镜像的每次写入确实被复制到所有镜像,而不是一直复制整个东西,你可以有一个 poke
在镜像中的给定索引处写入的函数(对于每种方法,(A)和(B))
void poke(int index, int value) {
int j;
for (j=0 ; j<NUMBER_OF_MIRRORS ; j++)
memory_mirror_starts[j][index] = value; // (A)
}
或
void poke(int index, int value) {
int j;
for (j=0 ; j<NUMBER_OF_MIRRORS ; j++)
memory[memory_mirror_starts[j] + index] = value; // (B)
}
拥有集中写入访问的功能可以向开发人员隐藏镜像的复杂性,并确保所有镜像确实正确更新。
备注index
可以检查为 >=0
和 < LENGTH_OF_MIRRORS
.
性能方面,
添加
inline
到函数声明将更改函数调用,函数代码就位,保存调用。poke
函数很小,代码不应该变大。(A) 基本上是
*(*(memory_mirror_starts + j) + index) = value
- (B) 基本上是
*(memory + *(memory_mirror_starts + j) + index) = value
- 所以 (A) 可能会快一点,(但优化器有他们的发言权,最好测试两种解决方案)
内联:
inline void poke(int index, int value) { ...
关于c - 将 X 索引的内存复制到 C 中单个数组中的多个位置的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33049574/