This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/TM4C1294NCPDT:能否因优化而删除互斥锁的类包装?

Guru**** 2589280 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/629715/compiler-tm4c1294ncpdt-can-a-class-wrapper-for-mutex-gate-be-removed-due-to-optimization

零件号:TM4C1294NCPDT

工具/软件:TI C/C++编译器

tirtos_tivac_2_10_01_38

CCS6

Arm 5.1

我想使用类包装来保护要由不同线程访问的全局变量,如以下代码(注意,为了简单起见,删除了一些初始化代码):

GateMutexPri句柄g_MutexHandle;

类MutexGateC:
{
公共:
MutexGateC()
{
M_IArg = GateMutexPri_Handenter(g_MutexHandle);
}

~MutexGateC()
{
GateMutexPri Leave (g_MutexHandle, m_IArg);
}

私人:
IArg m_IArg;
};

类HwiGateC:
{
公共:
HwiGateC()
{
M_Key = HWI_DISABLE();
}

~HWiGateC()
{
hwi_restore(m_Key);
}

私人:
UINT m_Key;
};

Uint g_resource1;

Uint g_resource2;

void Func1(void){

MutexGateC m();

g_resource1+;
}

作废Func2(void){

HwiGateCh();

g_resource2+;
}

 

我的问题是,在函数“Func1”和“Func2”中,变量“m”和“h”是否可以因优化而被删除,因为看起来变量从未被引用过? 如果可能,那么在哪个优化级别上? 谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    注意,您将m和h声明为函数(请参见“最复杂的分析”)。

    也就是说,一旦您更正了定义,编译器应该能够在几乎任何优化级别内联构造函数和析构函数。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢,我 之前没有注意到"最复杂的分析"。

    因此,如果我使用"MutexGateC m"和"HwiGateC h",由于优化,变量不会被删除,因为它们看起来没有被函数的其余代码引用?  是否有标准保证?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [QUETE USER="Jianyi Bao "]因此,如果我使用"MutexGateC m"和"HwiGateC h",由于优化,变量不会被删除,因为它们看起来没有被函数的剩余代码引用?[/QUOT]

    它们可以被删除。  编译器使用许多方法来标识和删除从未使用过结果的计算。  其中一些方法适用于所有优化级别。  也就是说,优化级别越高,这些方法越成功。

    Jianyi Bao 说:
     是否有标准保证?[/QUOT]

    有关编译器优化的详细信息不是标准的一部分。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    变量完全有可能被删除,但调用函数的构造函数和析构函数的跟踪仍将保留。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果需要确保变量未被删除或优化,则需要将其声明为易失性。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨,pf,

    你所说的"留下的痕迹"是什么意思?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在代码中使用"MutexGateC m"和"HwiGateC h",并在优化级别2 (全局优化)和4 (整个程序优化)检查生成的汇编代码,发现在调用方的开头和结尾调用构造函数和析构函数。 那么,是否意味着可以安全地使用此代码来防止多线程访问?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="Jianyi Bao "]

    嗨,pf,

    你所说的"留下的痕迹"是什么意思?

    [/引述]

    这很复杂。 C++描述的是抽象计算机的行为,而不是实际二进制的样子。 实际上,编译器可以自由输出任何二进制文件

    1. 从main返回正确的值
    2. 执行I/O的方式与抽象计算机相同
    3. 以与抽象计算机相同的方式执行所有易失性访问

    例如(很抱歉,我不知道谁最先提出了这个问题),clang编译了以下C代码:

    #include <stdint.h>
    
    int mystem(uint64_t x)
    {
    INT SUM = 0;
    同时(x)
    {
    SUM++;
    x &= x -1;
    }
    返回总和;
    } 

    谜(无符号长):#@谜(无符号长)
    popcnt rax, RDI
    ret 

    没有循环,没有'sum'变量...编译器检测到函数在其输入中计数为1s,因此用单个popcnt指令替换了整个循环。

    也就是说,编译器不能删除或转换它不知道的代码行为。 无法删除仅在链接时解析的函数调用,因为它可以执行任意I/O (不考虑链接时优化)。

    因此,人们告诉您的是:

    1. 您可能无法在二进制文件中清楚地标识MutexGateC 'object'
    2. 但对GateMutexPrI_enter和GateMutexPrI_Leave的调用仍将存在


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢,Markus。