当前位置: 首页 > news >正文

南充建网站wordpress缓存清除缓存

南充建网站,wordpress缓存清除缓存,网页做成软件,在线制作二维码生成器4.4.3. X86Subtarget 在X86TargetMachine构造函数的105行调用了X86Subtarget构造函数来创建具体的目标机器对象。 4.4.3.1. FMV的支持#xff08;v7.0#xff09; V7.0将具体目标机器对象的生成推迟到第一次调用getSubtarget ()时才创建。不过#xff0c;为了方便起见v7.0 V7.0将具体目标机器对象的生成推迟到第一次调用getSubtarget ()时才创建。不过为了方便起见我们在这里把v7.0的实现也一起看了。在v7.0里getSubtarget ()是这样的 122       template typename STC const STC getSubtarget(const Function F) const { 123         return *static_castconst STC*(getSubtargetImpl(F)); 124       } 目标机器对象的创建由目标机器的getSubtargetImpl()完成。V7.0的这个改动是为了支持称为多版本函数的新特性。关于这个新特性可以参考这个网址Function multi-versioning in GCC 6 [LWN.net]下面是它的翻译关于LLVM有这么一篇论文。 CPU架构随着演进通常会获得有趣的新指令但应用程序开发者通常发现利用这些指令是困难的。不愿意失去后向兼容是阻碍开发人员使用更新的计算架构的主要障碍之一。函数多版本化function multi-versioningFMV首先出现在gcc 4.8是拥有函数多个实现的方式每个实现使用不同架构特定的指令集扩展。Gcc 6引入了对FMV的修改更容易向应用程序代码引入基于架构的优化。 尽管gcc与内核的新版本尝试在平台面市前公开使用新架构特性的工具但开发人员难以开始使用这些工具。当前C开发者有几个选择 编写自己代码的多个版本每个面向不同的指令集扩展这要求他们还要手动处理这些版本的运行时分发。生成二进制文件的多个版本每个面向不同的平台。选择一个最低的硬件要求不使用新平台上的技术。通常使用新架构技术的好处足以压倒集成的挑战。例如打开Intel先进向量扩展AVX会显著优化数学代码。AVX的第二个版本AVX2在第4代也称为Haswell的Intel Core处理器里引入是一个选择。在科学计算领域AVX2的好处广为人知。OpenBLAS库使用AVX2给予了像R语言这样的项目执行上2倍的加速它也在Python科学库里产生了显著的提高。这些性能提升是通过使用256比特指令、浮点融合乘加指令以及gather操作使每秒浮点操作FLOPS加倍获得的。 不过使用向量扩展VX技术意味着大量的开发、部署以及维护性工作。维护多个版本二进制文件的想法一个架构一个阻止开发者以及发行版本支持这些特性。 为多个架构优化某些关键函数当运行时二进制文件检测到CPU能力时执行它们会更好吗这样做的一个特性FMV实际上自gcc 4.8以来就存在但仅用于C。gcc 4.8里的FMV使得开发者容易指定一个函数的多个版本每个针对特定目标机器指令集优化。Gcc负责创建执行函数正确版本所需的分发代码。 要在C代码里使用FMV用户要指定函数的多个版本。例如在gcc 4.8 FMV文档里展示的代码     __attribute__ ((target (sse4.2)))     int foo(){        // foo version for SSE4.2        return 1;     }     __attribute__ ((target (archatom)))     int foo(){        // foo version for the Intel Atom processor        return 2;     }     int main() {        int (*p)() foo;        assert((*p)() foo());        return 0;     } Target()指示将对指令集扩展如sse4.2或指定架构如archatom编译函数。 这里对每个函数开发者需要为每个目标创建特殊的函数与代码。这将要求代码里额外的开销在FMV程序里代码行数的增加使得它更难以管理与维护。 幸好gcc 6解决了这个问题它使用单个属性来定义要支持的最小架构集在C及C代码里支持FMV。这使得开发可以利用增强指令的Linux应用变得容易无需为每个目标复制函数。 通过FMV来利用AVX的简单例子是使用数组加法这个例子是array_addition.c     #define MAX 1000000     int a[256], b[256], c[256];     __attribute__((target_clones(avx2,archatom,default)))     void foo(){         int i,x;               for (x0; xMAX; x){            for (i0; i256; i){               a[i] b[i] c[i];            }        }     }     int main() {         foo();         return 0;     } 正如我们可以看到的使用target_clones()指示支持架构的选择是相当简单的。开发者仅需要选择架构或要支持指令集扩展的最小集AVX2、Intel Atom、AMD或几乎任何gcc从命令行接受的架构选项。编译器将创建函数面向指定指令集的多个版本并在运行时选择正确的版本。 最终这个代码的object dump有对每个架构最优的汇编指令。例如 非AVX代码Atom     add    %eax,%edx AVX:     vpaddd 0x0(%rax),%xmm0,%xmm0 AVX2:     vpaddd (%r9,%rax,1),%ymm0,%ymm0 注意FMV的新实现向array_addition.c提供了使用Intel AVX、AVX2甚至Atom平台的寄存器与指令的能力。这个能力增大了应用程序可以不出现非法指令错误运行的平台的范围。 在gcc 6以前告诉编译器使用Intel AVX2指令将把二进制的兼容性限制在Haswell和更新的处理器。通过FMV里新加的特性编译器还可以产生AVX优化的代码在运行时将自动确保仅使用合适的版本。换而言之当二进制运行在Haswekk或更新的CPU上时将使用Haswell特定的优化当同一个二进制在前Haswell世代处理器上运行时它将回退到使用旧处理器支持的标准指令。 CPUID选择 在gcc 4.8里FMV有一个分发优先级而不是一个CPUID选择。分发次序基于目标属性对每个函数版本排序。带有更先进特性的函数版本有更高的优先级。例如面向AVX2的版本比面向SSE2的版本优先级更高。 为了保持分发的低代价使用了间接函数ifunc机制。该机制是GNU工具链的一个特性它允许开发者创建给定函数的多个实现在运行时使用一个解析器函数在其中选择。在启动早期这个解析器函数由动态载入器调用决定应用程序使用哪个实现。一旦做出了实现选择就固定下来在这个过程的生命期里不变了。 在gcc 6中解析器检查CPUID并调用相应的函数。它对每个二进制执行文件都做一次。因此当存在对FMV函数的多个调用时仅第一个调用会执行CPUID比较后续调用将通过一个指针找到要求的版本。这个技术已经用于几乎所有的glibc函数。例如glibc对每个架构都优化了memcpy()因此当调用时glibc将调用恰当优化的memcpy()。 代码大小影响 FMV将增加二进制代码的大小但这个影响可以最小化。代码大小的增加依赖于应用FMV的函数有多大以及要求版本的数量。如果最初二进制代码大小是CN是请求的版本数包括缺省R是这些函数占整个应用程序代码的比例新代码的大小将是     (1 - R) * C R * C * N 如果一个应用程序最热代码占总大小的1%且应用FMV支持三个架构缺省sse4.2avx2代码大小总共增加2%。在考虑今天的储存容量时这是相当小的影响。但这种影响必须基于部署模型来考虑。性能、维护性与增加的二进制代码间存在权衡因此对某种类型的部署FMV可能不是正确的选择比如物联网设备。 结果 下表展示了在不同处理器上使用不同gcc标记运行array_addition.c的执行时间 执行时间ms GCC标记 Haswell Skylake Broadwell Xeon Atom Ivy Bridge None 603 645 580 1413 2369 517 -O3 38 44 37 107 96 60 -O3 -mavx 26 32 26 73 SIGILL 45 -O3 -mavx2 26 32 26 73 SIGILL SIGILL -O3 (with FMV) 26 32 26 73 96 45 FMV版本使用下面的指示    __attribute__((target_clones(avx2,archatom,default))) SIGILL项表示对某些组合是非法指令。缺省的CFLAGS不是特别值得注意配置作为Clear Linux for Intel Architecture项目部分说明。 实例 今天越来越多行业部门从基于云的科学计算中获益。这些部门包括化工、财务以及分析应用程序。其中一个更受欢迎的科学计算库是用于Python的NumPy库。它包括了对大的、多维数组与矩阵的支持。它还有用于线性代数、傅里叶变换以及随机数生成等等的特性。 在一个诸如NumPy的科学库里使用FMV技术的好处通常是它得到良好的理解与接受。如果没有启用向量化SIMD寄存器里许多未用的空间浪费了。如果启用向量化在一条指令里编译器使用额外的寄存器执行更多的操作比如我们例子里更多整数加法。 由于FMV技术性能的提升运行在带有AVX2指令的Haswell机器上对科学计算内容可以到达3%。我们使用运行在1.8GHz的Skylake系统上的OpenBenchmarking.org numpy-1.0.2使用FMV运行时间是8400秒而在使用-O3编译时是8600秒。 性能提升归功于从向量化受益的NumPy代码里的函数。为了检测这些函数gcc提供了标记-fopt-info-vec。这个标记用于检测向量化候选函数。例如以这个标记构建NumPy将告诉我们文件fftpack.c有可以使用向量化的代码     numpy/fft/fftpack.c:813:7: note: loop peeled for vectorization to enhance alignment 查看NumPy源代码显示radfg()函数这是NumPy里支持的快速傅里叶变换的一部分执行大量可以使用AVX优化的数组加法。NumPy的补丁还未升级但指日可待。 250     const X86Subtarget * 251     X86TargetMachine::getSubtargetImpl(const Function F) const { 252       Attribute CPUAttr F.getFnAttribute(target-cpu); 253       Attribute FSAttr F.getFnAttribute(target-features); 254     255       StringRef CPU !CPUAttr.hasAttribute(Attribute::None) 256                           ? CPUAttr.getValueAsString() 257                           : (StringRef)TargetCPU; 258       StringRef FS !FSAttr.hasAttribute(Attribute::None) 259                          ? FSAttr.getValueAsString() 260                          : (StringRef)TargetFS; 261     262       SmallString512 Key; 263       Key.reserve(CPU.size() FS.size()); 264       Key CPU; 265       Key FS; 266     267       // FIXME: This is related to the code below to reset the target options, 268       // we need to know whether or not the soft float flag is set on the 269       // function before we can generate a subtarget. We also need to use 270       // it as a key for the subtarget since that can be the only difference 271       // between two functions. 272       bool SoftFloat 273           F.getFnAttribute(use-soft-float).getValueAsString() true; 274       // If the soft float attribute is set on the function turn on the soft float 275       // subtarget feature. 276       if (SoftFloat) 277         Key FS.empty() ? soft-float : ,soft-float; 278     279       // Keep track of the key width after all features are added so we can extract 280       // the feature string out later. 281       unsigned CPUFSWidth Key.size(); 282     283       // Extract prefer-vector-width attribute. 284       unsigned PreferVectorWidthOverride 0; 285       if (F.hasFnAttribute(prefer-vector-width)) { 286         StringRef Val F.getFnAttribute(prefer-vector-width).getValueAsString(); 287         unsigned Width; 288         if (!Val.getAsInteger(0, Width)) { 289           Key ,prefer-vector-width; 290           Key Val; 291           PreferVectorWidthOverride Width; 292         } 293       } 294     295       // Extract required-vector-width attribute. 296       unsigned RequiredVectorWidth UINT32_MAX; 297       if (F.hasFnAttribute(required-vector-width)) { 298         StringRef Val F.getFnAttribute(required-vector-width).getValueAsString(); 299         unsigned Width; 300         if (!Val.getAsInteger(0, Width)) { 301           Key ,required-vector-width; 302           Key Val; 303           RequiredVectorWidth Width; 304         } 305       } 306     307       // Extracted here so that we make sure there is backing for the StringRef. If 308       // we assigned earlier, its possible the SmallString reallocated leaving a 309       // dangling StringRef. 310       FS Key.slice(CPU.size(), CPUFSWidth); 311     312       auto I SubtargetMap[Key]; 313       if (!I) { 314         // This needs to be done before we create a new subtarget since any 315         // creation will depend on the TM and the code generation flags on the 316         // function that reside in TargetOptions. 317         resetTargetOptions(F); 318         I llvm::make_uniqueX86Subtarget(TargetTriple, CPU, FS, *this, 319                                             Options.StackAlignmentOverride, 320                                             PreferVectorWidthOverride, 321                                             RequiredVectorWidth); 322       } 323       return I.get(); 324     } MFV需要多个目标机器可用因此现在使用容器SubtargetMap类型mutable StringMapstd:: unique_ptrX86Subtarget来保存多个X86Subtarget实例键值是描述目标CPU以及各方面特性的字符串这个字符串确保唯一。 317行的resetTargetOptions()根据当前函数的属性改写由InitTargetOptionsFromCodeGenFlags()等根据编译命令行设置的属性。 在318行创建X86Subtarget实例。 289     X86Subtarget::X86Subtarget(const Triple TT, const std::string CPU, 290                                const std::string FS, const X86TargetMachine TM, 291                                unsigned StackAlignOverride) 292         : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others), 293           PICStyle(PICStyles::None), TargetTriple(TT), 294           StackAlignOverride(StackAlignOverride), 295           In64BitMode(TargetTriple.getArch() Triple::x86_64), 296           In32BitMode(TargetTriple.getArch() Triple::x86 297                       TargetTriple.getEnvironment() ! Triple::CODE16), 298           In16BitMode(TargetTriple.getArch() Triple::x86 299                       TargetTriple.getEnvironment() Triple::CODE16), 300           TSInfo(), InstrInfo(initializeSubtargetDependencies(CPU, FS)), 301           TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) { 302       // Determine the PICStyle based on the target selected. 303       if (TM.getRelocationModel() Reloc::Static !isPositionIndependent()) { 304         // Unless were in PIC or DynamicNoPIC mode, set the PIC style to None. 305         setPICStyle(PICStyles::None); 306       } else if (is64Bit()) { 307         // PIC in 64 bit mode is always rip-rel. 308         setPICStyle(PICStyles::RIPRel); 309       } else if (isTargetCOFF()) { 310         setPICStyle(PICStyles::None); 311       } else if (isTargetDarwin()) { 312         if (TM.getRelocationModel() Reloc::PIC_)                                                                       ß v7.0删除 313           setPICStyle(PICStyles::StubPIC); 314         else { 315           assert(TM.getRelocationModel() Reloc::DynamicNoPIC); 316           setPICStyle(PICStyles::StubDynamicNoPIC); 317         } 318       } else if (isTargetELF()) { 319         setPICStyle(PICStyles::GOT); 320       } CallLoweringInfo.reset(new X86CallLowering(*getTargetLowering()));                           ß v7.0增加 Legalizer.reset(new X86LegalizerInfo(*this, TM)); auto *RBI new X86RegisterBankInfo(*getRegisterInfo()); RegBankInfo.reset(RBI); InstSelector.reset(createX86InstructionSelector(TM, *this, *RBI)); 321     } 基类X86GenSubtargetInfo的构造函数是TableGen生成的前面我们已经看到它将MC层的一组指针指向X86目标机器特定的参数。300行的成员TSInfo的类型是X86SelectionDAGInfo目标机器通过它可以提供对memcpy、memmove、memset、memcmp、memchr、strcpy、strcmp、strlen这些操作的专属处理代码v7.0删除这个调用。 303行的isPositionIndependent()检查使用的重定位模型是否为Reloc::PIC_这些重定位模型用于动态库的生成。V7.0简化为这几种StubPICi386-darwin的picGOT全局对象表32位elf的picRIPRel相对RIP64位elf的picNone没有使用pic。位置无关代码参考有关资料如《C高级编译》。
http://www.pierceye.com/news/169570/

相关文章:

  • 网站建设规划方案ppt模板wap浏览器安卓版
  • 网站关键词优化教程成都展厅设计公司
  • 百度网站排名软件怎么做网站竞价
  • 设计素材网站校园二手市场网站建设
  • 电子产品网站设计asp做微网站
  • 网站内部优化建设温州 网站制作
  • 怎么自己做网站地图网站涉及敏感视频等该怎么做
  • 个人网站建设主要功能南京自助建站网站
  • 替别人做设计的网站商业空间
  • 做网站很赚钱吗郴州网站定制
  • 霞浦建站公司建设通是个什么网站
  • 帮企业建网站网络广告有哪些
  • 网站的访问量怎么查知名电子商务网站
  • 鸣蝉小程序制作平台南通seo排名公司
  • 建设网站都要学些什么网站开发承包合同
  • 网站搭建好了怎么上到服务器好看wordpress主题
  • 免费自己制作网站教程网站文字格式
  • 模板建站教程网站建设公司特色
  • 广州网站设计制作江门住房与城乡建设局官方网站
  • 电子商城网站建设参考文献新手建立企业网站流程
  • 站长工具使用wordpress搜索框制作教程
  • 上海翼成信息科技有限公司做的什么网站怎么办一个网站
  • 上海网站建设的英文wordpress login 图标
  • 雅安市网站建设搭建网站工具
  • 网站如何做301重定向南宁一站网 给网站做营销
  • 网站 使用的字体女生电子商务专业适合做什么
  • 电商网站首页模板连云港 网站 建设
  • 自助建站广告发布企业年检网上申报流程
  • 河北平台网站建设价位外包网站有哪些
  • 做网站客户需要提供的资料梧州网站建设推荐