我的问题很简单,但我找不到任何明确的答案,所以我在这里。
如今,C编译器比几年前更有效率。重新定义是否还有任何优势……
这里有几点,可能已在上面提到:
这个问题只是一个问题,而不是一个意见问题,因为你已经具体了解了目标和工具链。不可能概括(并且从未有过)。
GNU ARM工具链使用Newlib C库。 Newlib旨在与架构无关且可移植。因此它是用C而不是汇编语言编写的,因此它的性能由编译器的代码生成决定,反过来在构建库时应用编译器选项。可以为非常特定的ARM体系结构构建,或构建更通用的ARM指令子集;这也会影响表现。
此外,Newlib本身可以使用各种条件编译选项构建,例如 PREFER_SIZE_OVER_SPEED 和 __OPTIMIZE_SIZE__ 。
PREFER_SIZE_OVER_SPEED
__OPTIMIZE_SIZE__
现在,如果你能够生成比编译器更好的ARM汇编程序代码(并且有时间),那么这很好,但是这种kung-foo编码技能越来越少,而且坦率地说越来越不必要了。你是否有足够的汇编程序专业知识来击败编译器;你有时间,你真的想为你可能使用的每个架构做到这一点吗?这可能是一个不成熟的优化,而且相当无效。
在某些情况下,在具有该功能的目标上,可能值得设置内存到内存的DMA传输。 GNU ARM编译器不会生成DMA代码,因为它依赖于芯片供应商,而不是ARM体系结构的一部分。然而 memcpy 是任意复制大小对齐和线程安全的一般目的。对于DMA最佳的特定情况,可能更好地定义一个新的不同命名的例程,并在需要的地方使用它而不是重新定义 memcpy 并且对于可能占主导地位的小型副本或多线程应用程序而言,它可能是次优的。
memcpy
实施 memcpy() 以Newlib为例可以看出 这里 。这是一个合理的惯用实现,因此同情一个典型的编译器优化器,它通常最适用于惯用代码。替代实现可以在未优化的编译中执行得更好,但是如果它是“不寻常的”,则优化器可能也不起作用。如果你用汇编程序编写它,你只需要比编译器更好 - 你将是一种罕见但不一定有价值的(商业)商品。也就是说,看看这个特定的实现,对于速度超过大小的实现来说,对于大的未对齐块来说效率确实低得多。有可能以较小的费用改进这一点,或许可以用于更常见的对齐副本。
memcpy()