Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在数组中使用int或char?_C_Performance_Struct_Char_Int - Fatal编程技术网

在数组中使用int或char?

在数组中使用int或char?,c,performance,struct,char,int,C,Performance,Struct,Char,Int,假设我在C中有一个数组,其中有5个元素包含[0..255]范围内的整数,在性能方面使用无符号字符、无符号整数或整数通常会更好吗?因为一个字符只有一个字节,但据我所知,对于处理器来说,int更容易处理。还是主要取决于元素的访问方式 编辑:测量非常困难,因为代码属于库,并且数组是从外部访问的 而且,我不仅在这种情况下遇到了这个问题,所以我要求得到一个更一般的答案,这是不可能回答的,因为它取决于代码、编译器和处理器 然而,一个建议是使用uint8\u t代替无符号字符。(代码将是相同的,但显式版本更好

假设我在C中有一个数组,其中有5个元素包含[0..255]范围内的整数,在性能方面使用
无符号字符
无符号整数
整数
通常会更好吗?因为一个字符只有一个字节,但据我所知,对于处理器来说,int更容易处理。还是主要取决于元素的访问方式

编辑:测量非常困难,因为代码属于库,并且数组是从外部访问的


而且,我不仅在这种情况下遇到了这个问题,所以我要求得到一个更一般的答案,这是不可能回答的,因为它取决于代码、编译器和处理器

然而,一个建议是使用
uint8\u t
代替
无符号字符。(代码将是相同的,但显式版本更好地传达了含义。)


那么还有一件事要考虑。最好将四个8位整数打包成一个32位整数。只要没有溢出(除法是明显的例外),大多数算术和位逻辑运算都可以正常工作。

黄金法则:测量它。如果你不介意测量它,那么它就不值得优化。所以,用一种方法来测量,改变它,用另一种方法来测量,用更快的方法来测量。请注意,当您切换到其他编译器或其他处理器(如2015年或2016年推出的处理器)时,其他代码可能会更快

或者,不要测量它,而是编写可读性和可维护性最好的代码


并考虑使用一个单一的64位整数和移位操作:-)/p>< p>而答案实际上取决于CPU以及它如何处理存储小整数的加载,您可以假设在大多数现代系统中字节数组将更快:


char
只占用
int
所占空间的1/4(在大多数系统上),这意味着在
char
数组上工作只占用内存带宽的四分之一。大多数代码都是现代硬件上的内存限制。

对于5个元素,使用int。对于大尺寸,使用profile。如果整个东西都可以放在缓存中,那么位屏蔽的成本可能会被抵消。缓存是您必须测试的东西。@sp2danny int,因为它“更方便”(对于处理器)?@Kapichu yes,不需要bitmasking@sp2danny这到底是什么意思?看我的编辑,测量很困难,既然访问方式取决于lib的用户,那么打包字节有什么好处?在内存中,它们就像我把它们当作单独的字节一样。例如,如果你需要将所有值乘以5,你只需要执行一次乘法。这对于位掩码特别有用,但只要没有溢出,就可以处理很多操作。如果您担心溢出,可以将四个8位整数打包成64位整数。这为溢出提供了足够的空间。(这种打包的有用性在很大程度上取决于手头的任务。)但是打包比较慢,不是吗?哦,因为这些值彼此无关,所以打包甚至没有意义(它们永远不会相乘),正如我所说的,这实际上取决于应用程序。没有单一的正确答案,因为这完全取决于你从哪里获得数据,以及你如何使用数据。例如,索引32位值通常是最快的,但如果这导致数据从CPU缓存溢出,则打包存储可能会更快?因为我知道一个整型比一个字符快。谁告诉你的?在AMD-64上,将一个字节加载到寄存器中只是一个操作,与它是有符号的还是无符号的无关,并且符号/零扩展不是让CPU汗流浃背的操作。您可以通过编译带有
-Os-S
标志的
intfoo(unsignedchar*bar){return*bar;}
变体并查看生成的.S文件来检查您的体系结构。我想我记得PowerPC需要第二条指令来加载
有符号字符
,这给操作增加了一个周期。但主内存负载可能需要约25个周期。这是一个重要的数字。正如我所说的,“位屏蔽”操作并不能让CPU出汗。考虑一下所需的硬件:您只需要将这些额外的位与质量连接起来。那是几根电线,不需要逻辑。与添加两个64位数字的复杂性形成鲜明对比,其中第一位的执行可能会或可能不会影响第64位的结果。许多现代CPU可以在一个周期内完成后面的工作。如果有一条指令,那么将一个字节加载到一个整数寄存器中的开销是零的。对于存储,从来没有开销。