让指针数组中的所有指针指向C中的相同对象?
我有两个定义:让指针数组中的所有指针指向C中的相同对象?,c,performance,pointers,memory,C,Performance,Pointers,Memory,我有两个定义: uint8_t *idx[0x100]; uint8_t raw[0x1000]; 除了循环idx的每个元素以将它们全部指向原始[0]之外,还有其他方法吗 一定有比这更快的方法↑ 那个指针是否有一个与memset等价的方法?简单、直接的循环可能是最好的方法。正如其他人指出的那样,请注意当前循环中存在错误 这样做的好处是,这种循环非常容易优化,这是一种常见的情况,编译器已经非常擅长于此,您的编译器将根据需要使用向量指令和其他优化,以保持非常快的速度,而无需手动优化自己。 当然,
uint8_t *idx[0x100];
uint8_t raw[0x1000];
除了循环idx的每个元素以将它们全部指向原始[0]之外,还有其他方法吗
一定有比这更快的方法↑ 那个指针是否有一个与memset等价的方法?简单、直接的循环可能是最好的方法。正如其他人指出的那样,请注意当前循环中存在错误 这样做的好处是,这种循环非常容易优化,这是一种常见的情况,编译器已经非常擅长于此,您的编译器将根据需要使用向量指令和其他优化,以保持非常快的速度,而无需手动优化自己。 当然,同时,它比手工优化更具可读性和可维护性
当然,如果有特殊情况,例如,如果您想用空指针填充它,或者如果您知道编译时的内容,那么有一些更有效的方法可以做到这一点,但在一般情况下,让编译器轻松优化代码是获得良好性能的最简单方法。简单、直接的循环可能是最好的方法。请注意,正如其他人指出的,当前循环中存在错误 这样做的好处是,这种循环非常容易优化,这是一种常见的情况,编译器已经非常擅长于此,您的编译器将根据需要使用向量指令和其他优化,以保持非常快的速度,而无需手动优化自己。 当然,同时,它比手工优化更具可读性和可维护性
当然,如果有特殊情况,例如,如果您想用空指针填充它,或者如果您知道编译时的内容,那么有一些更有效的方法可以做到这一点,但在一般情况下,使编译器易于优化代码是获得良好性能的最简单方法。我们只看到一段代码,如果要初始化指针的全局数组以指向uint8的全局数组,有一种更快的方法:编写显式初始值设定项。初始化在编译时完成,在执行时几乎不花费时间 如果阵列是自动的,恐怕没有更快的方法。如果您的编译器很聪明,并且被指示使用优化-O2、-O3等,它可能会展开循环并生成相当高效的代码。查看程序集输出以验证这一点。如果没有,您可以自己展开循环: 假设数组大小是4的倍数:
for (i = 0; i < sizeof(idx) / sizeof(*idx); i += 4)
idx[i] = idx[i+1] = idx[i+2] = idx[i+3] = &raw[0];
使它更方便,但如果a是指针,则隐藏问题。我们只看到一段代码,如果您正在初始化指针的全局数组以指向uint8\t的全局数组,则有一种更快的方法:编写显式初始值设定项。初始化在编译时完成,在执行时几乎不花费时间 如果阵列是自动的,恐怕没有更快的方法。如果您的编译器很聪明,并且被指示使用优化-O2、-O3等,它可能会展开循环并生成相当高效的代码。查看程序集输出以验证这一点。如果没有,您可以自己展开循环: 假设数组大小是4的倍数:
for (i = 0; i < sizeof(idx) / sizeof(*idx); i += 4)
idx[i] = idx[i+1] = idx[i+2] = idx[i+3] = &raw[0];
使它更方便,但如果a是指针,则隐藏问题。从性能工程的角度来看,确实有一种方法可以使它比
for (i=0; i<sizeof(raw); i++)
idx[i] = &raw[0];
如果在编译器中关闭优化器后进行比较。但差别可能很小
让我们开始吧:
uint8_t *idx[0x100];
uint8_t raw[0x1000];
#define lengthof(arr) (sizeof(arr) / sizeof(*arr))
uint8_t *start = idx;
int length = lengthof(idx);
uint8_t *end = idx + (length & ~1);
for (; start < end;)
{
*start++ = raw;
*start++ = raw;
}
if (length & 1)
*start++ = raw;
这一速度更快主要是因为两个原因:
直接操作指针。如果执行idx[i],在汇编中,每次都将执行idx+i*sizeof*idx,而*start已经得到了答案。
在每次迭代中重复操作。通过这种方式,代码在保持局部性的同时将具有较少的分支。gcc-O2很可能会为您带来好处。
从性能工程的角度来看,确实有一种方法可以比
for (i=0; i<sizeof(raw); i++)
idx[i] = &raw[0];
如果在编译器中关闭优化器后进行比较。但差别可能很小
让我们开始吧:
uint8_t *idx[0x100];
uint8_t raw[0x1000];
#define lengthof(arr) (sizeof(arr) / sizeof(*arr))
uint8_t *start = idx;
int length = lengthof(idx);
uint8_t *end = idx + (length & ~1);
for (; start < end;)
{
*start++ = raw;
*start++ = raw;
}
if (length & 1)
*start++ = raw;
这一速度更快主要是因为两个原因:
直接操作指针。如果执行idx[i],在汇编中,每次都将执行idx+i*sizeof*idx,而*start已经得到了答案。
在每次迭代中重复操作。通过这种方式,代码在保持局部性的同时将具有较少的分支。gcc-O2很可能会为您带来好处。
没有其他方法。同样,这样会使缓冲区溢出-sizeof提供数组的大小(以字节为单位),而不是数组计数。你想要的是i=0;i