intel - 为什么 Intel Haswell XEON CPU 偶尔会错误计算 FFT 和 ART?

标签 intel cpu-architecture processor avx2

在最后几天,我观察到我无法解释的新工作站的行为。对这个问题做一些研究,INTEL Haswell architecture 中可能存在一个可能的错误。以及在当前的 Skylake Generation 中。
在写可能的错误之前,让我给您概述一下所使用的硬件、程序代码和问题本身。
工作站硬件规范

  • 英特尔至强 E5-2680 V3 2500MHz 30M 缓存 12 核
  • Supermicro SC745 BTQ -R1K28B-SQ
  • 4 x 32GB ECC 注册 DDR4-2133 内存
  • 英特尔 SSD 730 系列 480 GB
  • NVIDIA Tesla C2075
  • 英伟达泰坦

  • 有问题的操作系统和程序代码
    我目前正在运行 Ubuntu 15.04 64 位桌面版本,安装了最新的更新和内核内容。除了用这台机器开发CUDA内核之类的东西,我最近测试了一个纯C程序。
    该程序正在做一些修改 ART在相当大的输入数据集上。所以代码执行了一些 FFT 并花费了相当长的时间来完成计算。我目前无法发布/链接到任何来源
    代码,因为这是无法发表的正在进行的研究。如果您不熟悉 ART ,只是一个简单的解释它的作用。 ART 是一种用于重建从计算机断层扫描仪接收到的数据的技术,以获得
    用于诊断的可见图像。所以我们的代码版本重建了像 2048x2048x512 这样大小的数据集。到目前为止,没有什么特别的,也没有涉及火箭科学。经过几个小时的调试和修复错误,代码被测试
    在引用结果上,我们可以确认代码按预期工作。代码使用的唯一库是标准的 math.h .没有特殊的编译参数,没有可能带来额外问题的额外库内容。
    观察问题
    该代码使用一种技术来实现 ART,以最小化重建数据所需的投影。所以让我们假设我们可以重建涉及 25 个投影的一片数据。该代码以 12 个内核上完全相同的输入数据开始。请注意,
    实现不是基于多线程,目前启动了 12 个程序实例。我知道这不是最好的方法,强烈建议涉及适当的线程管理,这已经在改进列表中了:)
    因此,当我们运行至少两个程序实例(每个实例都在一个单独的数据切片上工作)时,某些投影的结果以随机方式是错误的。为了让您了解结果,请参见表 1。请注意,输入数据始终相同。
    只运行涉及一个CPU核心的代码的一个实例,结果都是正确的。即使执行一些涉及一个 CPU 内核的运行,结果仍然是正确的。仅涉及至少两个或更多内核会生成如表 1 所示的结果模式。
    Table1: randomly wrong results from Haswell XEON CPU
    识别问题
    好的,这花了好几个小时才知道到底出了什么问题。所以我们检查了整个代码,大多数问题都是从一个小的实现错误开始的。但是,好吧,不(当然,我们不能证明不存在错误,也不能保证)。为了验证我们的代码,我们使用了两台不同的机器:
  • (Machine1) Intel Core i5 四核(2009 年末的型号)
  • (Machine2) 在 Intel XEON 6 核 SandyBridge CPU 上运行的虚拟机

  • 令人惊讶的是,Machine1 和 Machine2 总是产生正确的结果。即使使用所有 CPU 核心,结果仍然正确。在每台机器上运行超过 50 次,甚至没有一个错误结果。代码在每台目标机器上编译,没有优化选项或任何特定的编译器设置。
    因此,阅读新闻导致以下发现:
  • ArsTechnika - Skylake CPU freezes during complex workload
  • PcWorld - how to test your PC for the skylake bug
  • Intel Community - Simple instruction for freezing a Skylake Processor

  • 所以人们在 Prime95Mersenne Community似乎是第一个发现和识别这个的nasty bug .引用的帖子和新闻支持了这种怀疑,即问题只存在于繁重的工作量下。根据我的观察,我可以确认这种行为。
    问题
  • 您/社区是否在 Haswell CPU 和 Skylake CPU 上观察到这个问题?
  • 由于 gcc 执行默认的 AVX(2) 优化(只要可能),关闭此优化会有所帮助吗?
  • 我如何编译我的代码并确保 任何 可能受此错误影响的优化已关闭?到目前为止,我只阅读了有关使用 Haswell/Skylake 架构中的 AVX2 命令集的问题。

  • 解决方案?
    好的,我可以关闭所有 AVX2 优化。但这会减慢我的代码速度。英特尔可能会向主板制造商发布 BIOS 更新,以修改英特尔 CPU 中的微代码。由于它似乎是一个硬件错误,因此即使更新 CPU 微代码,这也可能变得有趣。我认为这可能是一个有效的选择,因为英特尔 CPU 使用一些由微码控制的 RISC 到 CISC 转换机制。
    编辑:Techreport.com - Errata prompts Intel to disable TSX in Haswell, early Broadwell CPUs将检查我的 CPU 中的微码版本。
    EDIT2:截至目前 (19.01.2016 15:39 CET) Memtest86+ v4.20 正在运行并测试内存。由于这似乎需要相当长的时间才能完成,我将在明天用结果更新帖子。
    EDIT3:截至目前 (21.01.2016 09:35 CET) Memtest86+ 完成了两次运行并通过了。甚至没有一个内存错误。从 revision=0x2d 更新了 CPU 的微码至 revision=0x36 .目前正在准备在这里发布的源代码。错误结果的问题包括。由于我不是相关代码的作者,因此我必须仔细检查不要发布我不允许发布的代码。我也在使用工作站并对其进行维护。
    EDIT4: (22.01.2016) (12:15 CET) 以下是用于编译源代码的 Makefile:
    # VARIABLES ==================================================================
    CC = gcc
    CFLAGS = --std=c99 -Wall
    #LDFLAGS = -lm -lgomp   -fast -s -m64 
    LDFLAGS = -lm 
    
    OBJ = ArtReconstruction2Min.o
    
    
    # RULES AND DEPENDENCIES ====================================================
    
    # linking all object files
    all: $(OBJ)
      
        $(CC) -o ART2Min $(OBJ) $(LDFLAGS)         
    
        
    # every o-file depends on the corresonding c-file, -g Option bedeutet Debugging Informationene setzen
    %.o: %.c
        $(CC)  -c -g $<  $(CFLAGS)
      
        
    # MAKE CLEAN =================================================================
    clean: 
        rm -f *.o
        rm -f main
    
    gcc -v输出:
    gcc -v
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-10ubuntu13' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13) 
    

    最佳答案

    编辑:问题解决了。我必须向社区大喊一声抱歉,并非常感谢您的提示。抱歉匿名用户,他似乎参与了内核开发。发生了什么?我们又花了 2 天时间调试和摆弄程序代码。没有发现实现问题。但是:主要代码涉及另一个帮助程序。这个帮助程序根据需要计算 ART 算法的权重。所以经过调试和测试,这个辅助程序在运行至少4个进程时搞砸了。所以这不是内核/硬件问题,而是软件(内存访问)问题。

    得到教训:

  • 调试参与计算过程的每个工具。
  • 微码已过时。 SuperMicro 已获悉此事。
  • Ubuntu 15.04 可能需要额外的工具,以便 CPU 的所有内核全速运行。通过安装 Ubuntu 14.04 - 所有内核都以 2.5GHz 运行来实现这一点。
  • 如果我们在 session 上见面,我需要喝点啤酒。

  • 因此,经过三天的思考、测试和摆弄机器后,我今天发现了以下观察结果:
  • Ubuntu 15.04 以每核 420 - 650 MHz 的频率运行 CPU。好吧,我认为这是一个节能选项,所以我按照各种指南将速度设置为最大值(2.50 GHz)。它没有用。与 cpufreq-utils 核对.
  • 在这台机器上多次测试后,结果仍然是错误的。其他(i5、i7、XEON)机器产生了正确的结果。
  • 我读到其他用户在 Ubuntu 15.04 和 CPU 频率方面遇到了问题。所以我决定插入 SSD 并安装 Ubuntu 14.04。再次检查 CPU 频率现在是多少……它显示出我预期的 2.50 GHz。
  • 再次启动重建算法(现在比 Ubuntu 15.04 快 4-5 倍)并等待结果。好的。结果现在是正确的!我仔细检查,启动了 9 个进程并比较了结果。还是正确的。

  • 所以我只能假设在这个 CPU 中使用 Speedstep 的 Ubuntu 15.04/内核可能存在问题。 15.04 中的 CPU 一直在 420 - 650 MHz 之间运行,而最低 CPU 速度预计为 1,20 GHz,最高 CPU 速度为 3,30 GHz。如果有人想要检查,我可以提供导致此问题的源代码和示例数据。

    抱歉怀疑这是 CPU 错误。

    编辑:经过一些更多的测试,问题只在某些情况下得到解决,但还没有解决。我会做更多的测试。

    关于intel - 为什么 Intel Haswell XEON CPU 偶尔会错误计算 FFT 和 ART?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34873123/

    相关文章:

    assembly - 带扩展的循环移位有何用途?

    有人可以用更简单的方式解释一下吗?

    c++ - float 与定点数 : what are the pros/cons?

    windows - 识别特定线程使用的处理器(核心)

    java - 在 MBA m1 Activity 监视器中,处理器名称 "java"显示 "kind" "intel"

    intel - 使用 SSE 指令进行 16 字节内存对齐

    c++ - 在 gcc 中的内联汇编程序中出错

    c - 为什么 10/3 在 C 中是准确的?

    caching - 什么是引用地点?

    c - 在 TMS320C6713 DSK 中运行代码时出错?