登录 立即注册

找到11871个回复

老虎会游泳 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,可防止【写指针写入数据后,编译器认为所有指针的数据缓存都失效不能用了,需要重新读取】。

不知这个想法对不对

老虎会游泳 36楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)
层主 @老虎会游泳 于 2023-01-27 17:20 删除了该楼层。
无名啊 34楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@老虎会游泳,我在给 SQLite 写流式解析 csv 的小插件,想只用一个缓冲区存储:数据块、某一行解析好的CSV数据。

比如,读取 4K 数据,然后边解析,边往这个缓冲区开头写入。

由于 CSV 数据解析完不会需要更多内存来存储,只会由于转义变得需要更少内存,所以不会发生写指针超出读指针问题。

所以,我在想写指针能不能加 restrict?加了有没有用?读指针需要加 restrict 吗?

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

@无名啊,对,restrict的作用应该是所有权的转移,规则应该和Rust类似:所有权转移给某别名之后,就不能再用其他别名访问了,但是转移之前则可以。

下一页 上一页 (298 / 594页)

3月29日 01:25 星期天

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1