标签:c-3 c performance structure kernel
我不记得看到像这个假设片段的代码示例:
cpu->dev.bus->uevent = (cpu->dev.bus->uevent) >> 16; //or the equivalent using a macro
其中大型结构中的成员使用指针取消引用,操作,并将结果分配回结构的同一字段.
内核似乎是一个频繁出现如此大型结构的地方,但我还没有看到它的例子,并对其原因产生了兴趣.
是否存在性能原因,可能与遵循指针所需的时间有关?这不是好风格,如果是这样,首选方式是什么?
解决方法:
它更多地是历史问题:内核主要是用C语言编写的(而不是C语言),并且 – 在最初的开发意图中 – (K& R时代)被认为是“高级汇编程序”,其陈述和表达应该具有C和ASM中的字面对应关系.在这种环境中,i i = 1且i = i 1是完全不同的东西,它们在完全不同的CPU指令中进行转换
当时编译器优化不那么先进和流行,所以通常首先将结果目标地址存储在本地临时变量(很可能是寄存器)中而不是分配,因此通常避免两次跟踪指针链的想法.
(如int * p =& a-> b-> c-> d; * p = a * p;)
或尝试使用compon指令,如a-> b-> c>> = 16;)
对于现今的计算机(多核处理器,多级高速缓存和管道),内部寄存器的执行速度可以比内存访问快十倍,遵循三个指针比在内存中存储地址更快,从而恢复“业务模型”的优先级”.
然后,编译器优化可以自由地更改生成的代码,使其足够大小或速度,具体取决于保留的内容更重要,具体取决于您使用的处理器类型.
所以 – 现在 – 如果你写i或i = 1或i = i 1并不重要:编译器很可能产生相同的代码,试图只访问i一次.并且在指针链两次之后很可能被重写为等效于(cpu-> dev.bus-> uevent)>> = 16,因为>> =对应于x86衍生处理器中的单个机器指令.
那说(“这并不重要”),代码风格也倾向于反映它首次编写时代的阶段和时尚(因为进一步的开发人员倾向于保持一致性).
你的代码本身并不“坏”,它在通常写的地方看起来很“奇怪”.
只是为了让您了解管道和预测是什么.考虑两个向量的比较:
bool equal(size_t n, int* a, int *b)
{
for(size_t i=0; i<n; ++i)
if(a[i]!=b[i]) return false;
return true;
}
在这里,一旦我们找到不同的东西,我们就会对它们进
现在考虑一下:
bool equal(size_t n, int* a, int *b)
{
register size_t c=0;
for(register size_t i=0; i<n; ++i)
c+=(a[i]==b[i]);
return c==n;
}
没有捷径,即使我们发现差异继续循环和计数.
但是从循环内部删除了if,如果n不是那么大(假设少于20),这可以快4到5倍!
优化的编译器甚至可以识别这种情况 – 证明没有不同的副作用 – 可以在第二个代码中重写第一个代码!
标签:c-3,c,performance,structure,kernel 来源: https://codeday.me/bug/20190722/1505783.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。