gpt4 book ai didi

c++ - 编译器会优化 for 循环以匹配总线宽度吗?

转载 作者:行者123 更新时间:2023-12-01 14:25:25 25 4
gpt4 key购买 nike

假设我想设置一个具有不同值的 char 数组,但为了简单起见:

char buff[1024];
...
for (int i = 0; i < 1024; i++) buff[i] = NULL;

编译器会优化它以匹配总线宽度吗?或者我应该手动执行此操作:

char buff[1024];
...
size_t empty = NULL;
for (int i = 0; i < 1024 / sizeof(size_t); i++)
memcpy(buff + i * sizeof(size_t), &empty, sizeof(size_t));

假设 sizeof(size_t) 是总线宽度。

我做了一些测量,我认为这恰好证明了上述观点:

#define TIMES 512
#define SIZE 4194304

int main(void) {

char *buff = new char[SIZE];

int times = TIMES;

clock_t begin = clock();

void *pattern = (void*)0xffeeddcc;

while (times--) {

... some for loop ...
};

clock_t end = clock();

delete[] buff;

std::cout << ((float)(end - begin) / CLOCKS_PER_SEC) << " s elapsed.\n";

return 0;
};

按字符设置字符:

for (int i = 0; i < SIZE; i++) buff[i] = i % 0xff;

平均耗时:13.6284 s

一次设置固定大小(总线宽度):

for (int i = 0; i < SIZE / sizeof(void*); i++) {
void* sub = (void*)(((i * sizeof(void*)) % 0xff) + (((i * sizeof(size_t) + 1) % 0xff) << 8) + (((i * sizeof(void*) + 2) % 0xff) << 16) + (((i * sizeof(void*) + 3) % 0xff) << 24));

memcpy(buff + i * sizeof(void*), &sub, sizeof(void*));
};

平均耗时:19.4352 s

逐个字符的模式:

for (int i = 0; i < SIZE; i++) buff[i] = ((char*)&pattern)[i % sizeof(void*)];

平均耗时:17.1696 s

图案固定尺寸(总线宽度):

for (int i = 0; i < SIZE / sizeof(void*); i++) memcpy(buff + i * sizeof(void*), &pattern, sizeof(void*));

平均耗时:5.6976 s

我不知道所有这些测量是否有必要 XD

使用 2 GHz、2 核 CPU(Intel Core i3-5005U CPU @ 2.00 GHz)完成。

最佳答案

如果您将每个 char 设置为相同的值,只需调用 memset

编译器(即 gcc 和 clang)确实可以识别像这样的循环

for (int i = 0; i < 1024; i++) buff[i] = 0xff;

Clang 将其转换为 memset 调用; gcc 使用一次设置一个单词的指令:https://gcc.godbolt.org/z/ovRTPU .但是调用 memset 会得到相同的汇编输出(它通常是编译器可识别的函数(如 memcpy))。

如果您将静态存储持续时间设置为 0 的缓冲区,则无需执行任何操作,因为在加载程序时它已经清零。

(顺便说一句,对 0 使用 NULL 不是一个好主意。至少在 C 中,NULL 可以是 ( void*)0 在没有警告/错误的情况下不会分配给整数类型。)

关于c++ - 编译器会优化 for 循环以匹配总线宽度吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62100407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com