【问题标题】:Is there really such a thing as a char or short in modern programming?现代编程中真的有 char 或 short 这样的东西吗?
【发布时间】:2010-05-01 17:00:25
【问题描述】:

在过去的几个月里,我一直在学习为 Mac 编程(我有其他语言的经验)。显然,这意味着学习 Objective C 语言,从而学习更简单的 C 语言。所以我偶然发现了这句话,它指的是一般的 C/C++ 语言,而不仅仅是 Mac 平台。

对于 C 和 C++,更喜欢使用 int 字符和短。背后的主要原因 这是 C 和 C++ 执行的 算术运算和参数 在整数级别传递,如果你有 一个可以放入 a 的整数值 字节,您仍然应该考虑使用 一个 int 来保存数字。如果你使用 一个字符,编译器将首先 将值转换为整数, 执行操作,然后 将结果转换回字符。

所以我的问题是,在 Mac 桌面和 iPhone OS 环境中是这种情况吗?我知道在谈论这些环境时,我们实际上是在谈论 3-4 种不同的架构(PPC、i386、Arm 和 A4 Arm 变体),因此可能没有一个答案。

尽管如此,一般原则仍然认为,在现代 32 位/64 位系统中,使用与机器的自然 4 字节字不一致的 1-2 字节变量并不能提供我们预期的很多效率。

例如,100,000 个字符的普通旧 C 数组比相同的 100,000 个整数小四倍,但如果在枚举期间,读取每个索引涉及各种类型的强制转换/装箱/拆箱,我们会尽管节省了内存开销,但看到整体“性能”较低?

【问题讨论】:

    标签: performance macos compiler-construction integer alignment


    【解决方案1】:

    与内存速度相比,处理器非常快。将值作为字符或短裤存储在内存中总是值得的(尽管为了避免移植问题,您应该使用 int8_t 和 int16_t)。将使用更少的缓存,并且将有更少的内存访问。

    【讨论】:

    • 这是我一直在遵循的原则,直到我遇到原始问题中的引用。因此,我是否正确地说您认为该断言是完全错误的,或者仅仅是不是黑白的事实。我承认这一点,以及对此处类似问题的常见回答(参见相关的“char 和整数数组之间的速度差异?”和“现代处理器上的内存对齐?”)仍然坚持认为时间关键型应用程序(例如因为那些处理大型数据集(如图形)的人受益于“对齐的方法”。
    • 对齐一个值以使其跨越字边界,尤其是高速缓存行边界是不好的。对于小的(8 位或 16 位)值,很容易避免它。您问题中的引用并没有过多地说明内存访问。我同意,当值在寄存器中时,使用 byte 或 short 通常不会买任何东西。
    • 与 L1 缓存未命中的成本相比,将内容移入和移出子字变量的位移非常快。您可以一次在缓存中容纳更多的小变量。线程之间共享的可变数据例外。在这种情况下,您实际上可能希望每个变量使用整个缓存行(大约 128 字节),即使它是布尔值,以防止错误共享。嵌入式处理器通常没有多级透明缓存,但大多数仍然具有片上 SRAM,它比片外 RAM 快一个数量级,因此在片上适应工作集是值得的。
    【解决方案2】:

    不能代表 PPC/Arm/A4Arm,但 x86 能够像 8 位、16 位或 32 位(如果 x86_64 处于 64 位模式,则为 64 位)一样处理数据,尽管我不确定是否编译器会利用这些指令。即使使用 32 位加载,编译器也可以将数据与清除高 16/24 位的掩码进行“与”运算,这会相对较快。

    很可能,将更多数据放入缓存的能力至少会抵消速度差异......尽管唯一确定的方法是实际分析代码。

    【讨论】:

    • 感谢您的回复!当然,像我这样的棘手问题总是假设性的,只有通过分析才能真正回答。我想我摆出的缪斯是我在问题中引用的原始引述,一个公认的普遍真理(由经验丰富的 C-dev 提供),或者仅仅是一种更多地作为事实呈现的观点。是否需要针对最佳情况做出判断,例如,随机访问与顺序、读取与写入、小集合(适合寄存器)与大集合(需要分页)。
    【解决方案3】:

    当然需要使用小于目标机器寄存器大小的数据结构。想象一下,您正在将编码为 UTF-8 或 ASCII 的文本数据存储在内存中,其中每个字符的大小大多类似于一个字节,您是否要将字符存储为 64 位数量?

    您正在寻找的建议是警告不要过度优化。 您必须在空间节省与您选择的计算性能之间取得平衡。

    我不会太担心,今天的现代 CPU 已经足够复杂,很难靠自己做出这种判断。选择明显的数据类型,让编译器担心其余的。

    【讨论】:

      【解决方案4】:

      x86架构的寻址模型是内存的基本单位是8位字节。

      这是为了简化字符串和十进制运算的操作。

      然后,为了获得有用的整数大小,指令集允许以 1、2、4 和(最近)8 个字节为单位使用这些。

      【讨论】:

      • 感谢您的回复!既然您提到了指令集...使用 x86 以 8 位字节为单位工作,因此像我引用的原始资料那样说它“更喜欢”以 4 字节为单位工作是不正确的,尤其是在使用时上证所?作者似乎建议的是,在时间紧迫的代码(例如图形处理)中,使用 char 参数声明函数将包括固有的 char 到 int 到 char 的转换,这可能比我们将参数声明为 int 时要慢,甚至如果我们事先知道我们的参数值永远不会超过 255。
      • @Dean:CPU 有寄存器,很可能是 32 位。这就是它“喜欢”的东西。显示我的年龄,第一台寻址字节的机器是 IBM 360。在此之前(IBM 7094),它们往往有 36 位可寻址字,但在此类机器中字符串操作非常笨拙。在现代机器中,几乎所有涉及字节的算术都涉及扩展到 32 位并返回,但速度非常快。只有在最严格的代码中才会有所作为。很少有人写出如此紧凑的代码,尽管他们想象自己总是这样做。
      • 再次感谢迈克,自从我发布这个问题以来,我一直在尝试执行一些分析器测试,以确定最佳使用/最佳案例方案。正如您正确识别的那样,经验证据似乎需要数百万次迭代才能在枚举性能上有明显差异。
      【解决方案5】:

      要记住的事实是,大多数软件开发都是针对不同的处理器编写的,而不是我们大多数人日常处理的。

      C 和汇编程序是这些的通用语言。

      2008 年制造了大约 100 亿个 CPU。每年生产的新 CPU 中约有 98% 是嵌入式的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-30
        • 2013-05-02
        • 1970-01-01
        • 2013-08-17
        • 2011-08-30
        • 1970-01-01
        • 1970-01-01
        • 2014-02-08
        相关资源
        最近更新 更多