登录 立即注册

找到11754个回复

无名啊 55楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,我能看懂一点点汇编,你说的我能理解。(看过半本墨绿色的 x86 汇编书,但没咋写过,又都忘得差不多了。。

老虎会游泳 54楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,寄存器没有内存地址,所以任何有地址的内容必然在内存,但是在内存不意味着慢,因为它还可以同时存在于L3/L2/L1缓存中,而且也不必马上写回内存。

任何不需要有内存地址的内容,都可以放进寄存器,只要寄存器还没满。

内容在不在寄存器是静态分配的,编译的时候就决定了,查看汇编代码就能看出来。

如果寄存器还没满,并且内容不需要有内存地址,编译器没有理由不把它放进寄存器,除非专门指示它不进行此类优化(-O0volatile)。

无名啊 53楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,不对,你看看 知乎那篇文章 提到的第三个例子,

修改了 this->target 的值(unsigned char 类型),导致编译器认为 this 也可能被修改了,所以后续每次 this->target 都要重新读取 this。。

(我记得 C++ 的 this 是只读的?还是啥?编译器咋会认为被修改了呢。。)

老虎会游泳 52楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,以下是可能的分配:

char buf[16]; // 数组只能在内存,因为数组访问操作涉及取地址。内存中的数据会自动逐级缓存在L3/L2/L1 Cache,该操作由CPU自动完成。
char *read_next = buf; // 指针本身可以在寄存器,指向的内容当然不在寄存器,只可能在内存和缓存中
char *write_next = buf + 16; // 指针本身可以在寄存器,指向的内容当然不在寄存器,只可能在内存和缓存中

如果一个内容可以被指针指向,意味着它一定有一个内存地址,也就是说它一定在内存中,当然它也可以同时在L3/L2/L1 Cache中,但不会在寄存器中。在寄存器中的内容没有内存地址。

但是指针本身(也就是内存地址这个数值本身)可以在寄存器中。

无名啊 51楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,意思是,拿某个寄存器来存 read_next,而不存入栈上了

好像写入数组末尾之后,是未定义行为。这么说,编译器认为 read_next 未被修改也无不可。。

哎,还是等写完之后,再加 restrict 试试吧。反正也不是啥速度极为严苛的场景,只是想顺便学学 restrict 而已

老虎会游泳 50楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊

缓存至寄存器

没有这种操作。

一个变量要么在寄存器,要么在内存,不会同时位于两者。

位于内存的变量只会被缓存到L3/L2/L1 Cache中,不会位于寄存器。而这个缓存操作是CPU自动进行的,不需要程序控制。

所以,变量在不在寄存器,看汇编代码就能知道,不需要运行时确定。

无名啊 49楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳

指针本身是否被优化到寄存器与restrict无关。如果不对指针进行取地址操作,它就可以被优化到寄存器。

char buf[16];
char *read_next = buf, *write_next = buf + 16;

*write_next = '\0'; // 此时 read_next 岂不就被修改了吗?(假设 read_next 就在 buf 后面)

编译器咋会放心把 read_next 缓存至寄存器的。。

老虎会游泳 48楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,至于43楼的设计到底能不能认为所有权发生了转移,我认为是值得争议的问题。

因为从瞬时来看,每个单独的时刻,所有权都从读指针转移到了写指针。

但从全局来看,所有权在读指针和写指针之间共享。

所以到底算不算转移,可能是“实现定义的”

无名啊 47楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,老虎用 restrict 的情景多吗?

我是不是要写完那个小插件,再试试加 restrict,才理解得更快呢。。

老虎会游泳 46楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊restrict针对的是指针指向的内容,不是指针本身。指针本身是否被优化到寄存器与restrict无关。如果不对指针进行取地址操作,它就可以被优化到寄存器。如果不确定,你可以用gcc -O2 -S查看汇编代码。

无名啊 45楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,感觉 43 楼的设计,没法加 restrict

那岂不读指针和结束指针都没法缓存至寄存器,每次读取前都要读一次内存?(因为编译器认为,写指针可能会修改 char *read_next, *end?)

老虎会游泳 44楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,我知道你想采用的方法。我的观点是如果不确定就不要使用。

注解
restrict 限定符(像寄存器存储类)是有意使用以促进优化的。而从所有组成一致程序的预处理翻译单元中,删除所有此限定符的实例不会影响其含义(即可观的行为)。
编译器可以忽略任何一个或全部使用 restrict 的别名使用暗示。
欲避免未定义行为,程序员应该确保 restrict 限定指针所做的别名引用断言不会违规。

此外实现类型转换解引用的另一个方案:

许多编译器提供作为 restrict 对立面的语言扩展:指示即使指针类型不同,也可以别名使用的属性: may_alias (gcc)

无名啊 43楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,画了个草图,容易理解:
image.png(13.01 KB)

老虎会游泳 42楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,有一个实验方法,就是用 gcc -O2 -S 编译一段函数,看看加restrict和不加有什么区别。

老虎会游泳 41楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,至于性能问题,据我所知编译器很少生成主动刷新CPU缓存的代码,大部分工作都是交由CPU自动完成的,除非涉及同步原语(信号量、互斥锁等)。

老虎会游泳 40楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,如果问题是阅读理解,我会回答“不行”。

若某个可由 P (直接或间接)访问的对象会被任何手段修改,则该块中所有对该对象(读或写)的访问,都必须经由 P 出现,否则行为未定义。

之前读和之后读都是读。文段中没有体现出时间前后的区别,只强调了定义域的区别。如果读访问发生在不含指针P的块中,则不会有问题。

无名啊 39楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,写指针 和 读指针,都指向同一块缓冲区。只是写指针写入过后的字符对象,都绝不再读取。(因为写指针不会超出读指针,如上所述)

无名啊 38楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,只是【通过 char * restrict 修改后,不再使用其他别名】,也不行?

因为解析了一个字符,并写入后,就不再需要读取这个及之前的字符对象了

老虎会游泳 35楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊,根据以下文段,我觉得所有权的转移是在声明时发生的,而非使用时发生的。所以只要这个定义域内存在“restrict 指针 P”,就不能通过其他手段访问。

在每个声明了 restrict 指针 P 的块(典型例子是函数体的执行,其中 P 为参数)中,若某个可由 P (直接或间接)访问的对象会被任何手段修改,则该块中所有对该对象(读或写)的访问,都必须经由 P 出现,否则行为未定义。

只有一种情况可以存在其他别名:“restrict 指针 P”指向的内容不会进行任何修改。

若对象决不被修改,则它可以被别名引用,并被异于 restrict 限定的指针访问。

无名啊 37楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,“对象类型”是指非函数类型。。

另外,只是指向 char 类型的读写指针。

另外,根据严格别名说的,char * 可修改任何类型的数据。

所以,我认为给 char * 添加 restrict,可防止【写指针写入数据后,编译器认为所有指针的数据缓存都失效不能用了,需要重新读取】。

不知这个想法对不对

下一页 上一页 (292 / 588页)

1月13日 22:11 星期二

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1