Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

优化编译器不必要地重新加载向量常量

Posted on 2022-12-07

肖像2018facebook.jpg

现代处理器具有强大的矢量指令,允许您一次加载多个值,并(在一条指令中)对所有这些值进行操作。同样,它们允许您拥有向量常量。因此,如果您想向大型数组中的所有整数添加一些整数(比如 10001),您可能首先加载一个值为 10001 的 8 倍的常量,然后您将从数组中加载元素,8 个元素乘以 8 个元素,添加矢量常量(因此一次做 8 次加法),然后存储结果。在其他条件相同的情况下,这可能会快 8 倍。

优化编译器甚至可以为您进行此优化(称为“自动矢量化”的过程)。但是,对于更复杂的代码,您可能需要使用“内部”函数(例如,_mm256_loadu_si256、_mm256_add_epi32 等)手动完成。

让我们考虑一下我描述的简单情况,但是我们同时处理两个数组……使用相同的常量:

 #包含< x86intrin.h >  
   
#包含< stdint.h >  
   
void process_avx2 ( const uint32_t * in1 , const uint32_t * in2 , size_t len ) {  
   
  // 定义常量,8 x 10001  
   
  __m256i c = _mm256_set1_epi32 ( 10001 ) ;  
   
  const uint32_t * finalin1 = in1 + len ;  
   
  const uint32_t * finalin2 = in2 + len ;  
   
  对于( ; in1 + 8 < = finalin1 ; in1 + = 8 ) {  
   
    // 将 8 个整数加载到一个 32 字节的寄存器中  
   
    __m256i x = _mm256_loadu_si256 ( ( __m256i * ) in1 ) ;  
   
    // 将刚刚加载的 8 个整数与 8 个常量整数相加  
   
    x = _mm256_add_epi32 ( c , x ) ;  
   
    // 存储修改后的 8 个整数  
   
    _mm256_storeu_si256 ( ( __m256i * ) in1 , x ) ;  
   
  } ;  
   
  对于( ; in2 + 8 < = finalin2 ; in2 + = 8 ) {  
   
    // 将 8 个整数加载到一个 32 字节的寄存器中  
   
    __m256i x = _mm256_loadu_si256 ( ( __m256i * ) in2 ) ;  
   
    // 将刚刚加载的 8 个整数与 8 个常量整数相加  
   
    x = _mm256_add_epi32 ( c , x ) ;  
   
    // 存储修改后的 8 个整数  
   
    _mm256_storeu_si256 ( ( __m256i * ) in2 , x ) ;  
   
  }  
   
}  
   

直到最近,我的期望是优化编译器会将常量保存在寄存器中,并且永远不会加载它两次。他们为什么会这样?

然而,您可以检查GCC 是否加载常量两次。

在这种情况下,其他编译器(如 LLVM)做得更好。然而,在其他情况下,LLVM 和 GCC 都愉快地加载常量不止一次。只有英特尔编译器 (ICC) 似乎能够以一定的一致性避免此问题。

有关系吗?在大多数情况下,这种效果对性能的影响应该很小。几乎可以肯定的是,每个函数的开销只有几条指令。但是,在规模上,它会增加包含许多常量的代码。 AVX-512 引入了新的掩模类型,它们也受到这种影响。

能够指示编译器不要重新加载常量会很有趣。您可能认为 static 关键字会有所帮助,但是对于 LLVM,静态向量变量可能会受到锁的保护,这可能会使您的代码更加繁重。

原文: https://lemire.me/blog/2022/12/06/optimizing-compilers-reload-vector-constants-needlessly/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme