You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

g++计时器与Intel oneAPI DPC++编译器兼容异常问题

HPCCG计时器在icpx编译下失效的问题分析与解决

问题现象

  • 使用Intel oneAPI编译器icpx编译HPCCG代码可成功编译,但所有时间统计值均为0,MFLOPS结果显示为inf
  • 使用g++编译时,计时器功能正常,能输出有效性能统计数据

计时器实现代码

//@HEADER
// ************************************************************************
// 
//               HPCCG: Simple Conjugate Gradient Benchmark Code
//                 Copyright (2006) Sandia Corporation
// 
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
// 
// BSD 3-Clause License
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
// 
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// 
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
// 
// ************************************************************************
//@HEADER
/////////////////////////////////////////////////////////////////////////

// Function to return time in seconds.
// If compiled with no flags, return CPU time (user and system).
// If compiled with -DWALL, returns elapsed time.

/////////////////////////////////////////////////////////////////////////
#ifdef USING_MPI
#include <mpi.h> // If this routine is compiled with -DUSING_MPI
                 // then include mpi.h
double mytimer(void)
{
   return(MPI_Wtime());
}


#elif defined(UseClock)

#include <time.hpp>
double mytimer(void)
{
   clock_t t1;
   static clock_t t0=0;
   static double CPS = CLOCKS_PER_SEC;
   double d;

   if (t0 == 0) t0 = clock();
   t1 = clock() - t0;
   d = t1 / CPS;
   return(d);
}

#elif defined(WALL)

#include <cstdlib>
#include <sys/time.h>
#include <sys/resource.h>
double mytimer(void)
{
   struct timeval tp;
   static long start=0, startu;
   if (!start)
   {
      gettimeofday(&tp, NULL);
      start = tp.tv_sec;
      startu = tp.tv_usec;
      return(0.0);
   }
   gettimeofday(&tp, NULL);
   return( ((double) (tp.tv_sec - start)) + (tp.tv_usec-startu)/1000000.0 );
}

#elif defined(UseTimes)

#include <cstdlib>
#include <sys/times.h>
#include <unistd.h>
double mytimer(void)
{
   struct tms ts;
   static double ClockTick=0.0;

   if (ClockTick == 0.0) ClockTick = (double) sysconf(_SC_CLK_TCK);
   times(&ts);
   return( (double) ts.tms_utime / ClockTick );
}

#else

#include <cstdlib>
#include <sys/time.h>
#include <sys/resource.h>
double mytimer(void)
{
   struct rusage ruse;
   getrusage(RUSAGE_SELF, &ruse);
   return( (double)(ruse.ru_utime.tv_sec+ruse.ru_utime.tv_usec / 1000000.0) );
}

#endif

编译输出对比

icpx编译结果

#********** Performance Summary (times in sec) ***********: 
Time Summary: 
  Total   : 0
  DDOT    : 0
  WAXPBY  : 0
  SPARSEMV: 0
FLOPS Summary: 
  Total   : 9.536e+06
  DDOT    : 596000
  WAXPBY  : 894000
  SPARSEMV: 8.046e+06
MFLOPS Summary: 
  Total   : inf
  DDOT    : inf
  WAXPBY  : inf
  SPARSEMV: inf

g++编译结果

#********** Performance Summary (times in sec) ***********: 
Time Summary: 
  Total   : 0.018251
  DDOT    : 0.001142
  WAXPBY  : 0.001825
  SPARSEMV: 0.014805
FLOPS Summary: 
  Total   : 9.536e+06
  DDOT    : 596000
  WAXPBY  : 894000
  SPARSEMV: 8.046e+06
MFLOPS Summary: 
  Total   : 522.492
  DDOT    : 521.891
  WAXPBY  : 489.863
  SPARSEMV: 543.465

问题原因与解决方法

核心原因

icpx的优化逻辑(默认或显式指定的高优化级别)可能误将计时器相关代码优化:

  1. 默认使用的getrusage获取CPU时间的逻辑,被编译器优化后返回值始终为0
  2. 静态变量初始化或时间差计算步骤被优化,导致时间差恒为0

解决步骤

  1. 禁用针对性优化:
    • 编译时添加-O0关闭所有优化,验证是否为优化导致的问题
    • 若需保留部分优化,可针对计时器代码添加-fno-inline或-foptimize-sibling-calls,避免计时器函数被内联优化
  2. 切换计时器实现:
    • 编译时添加-DWALL宏,使用gettimeofday实现的墙钟时间,该实现受优化影响更小
    • 或添加-DUseTimes,使用times系统调用获取CPU时间
  3. 升级编译器版本:
    • 旧版Intel oneAPI编译器可能存在优化bug,升级至最新版本可修复该问题

内容的提问来源于stack exchange,提问作者Selorm K.aw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:12:32