C++编译器与操作系统调用约定解析

需积分: 2 0 下载量 89 浏览量 更新于2024-07-09 收藏 1.02MB PDF 举报
"调用公约,不同os下编译差异" 这篇文档《calling_conventions.pdf》主要探讨了在不同C++编译器和操作系统中调用约定(也称为调用约定或函数调用规范)的差异。作者Agner Fog详细阐述了与编译相关的各种技术细节,包括数据表示、对齐、栈对齐、寄存器使用、函数调用约定以及名字修饰(名称混淆)。以下是关键知识点的概述: 1. **调用约定标准化的需求**:调用约定是编程语言中约定如何传递参数、返回值和处理函数调用的规则。由于不同的编译器和操作系统可能有不同的实现,因此需要标准化来确保跨平台兼容性。 2. **数据表示**:不同平台和编译器可能采用不同的方式来表示数据类型,如整型、浮点型等,这会影响到函数调用中的数据传递。 3. **数据对齐**:数据对齐是指内存中的数据结构按照特定规则排列,以优化访问效率。不同的系统可能有不同的对齐策略,这对函数参数的存储和传递有直接影响。 4. **栈对齐**:栈在函数调用时用于存储临时数据和参数。栈对齐确保每次函数调用后栈指针保持在特定的边界上,以满足处理器的性能要求。 5. **寄存器使用**:不同的编译器可能会为不同类型的函数参数分配特定的寄存器,例如,某些编译器可能在64位Windows中允许使用浮点寄存器,而在其他系统中可能不支持。此外,还有对YMM向量寄存器、ZMM向量寄存器的讨论,这些是用于高速处理矢量化数据的寄存器。 6. **函数调用约定**:这部分详细介绍了如何传递和返回对象,特别是SIMD(单指令多数据)类型,这是现代处理器中用于加速计算的特性。 7. **名字修饰**(Name Mangling):为了解决C++的命名空间、重载函数等问题,编译器会对标识符进行编码,形成机器可识别的名称。文档列举了微软、Borland、Watcom、GNU、Intel、Symantec和Digital Mars等编译器的名字修饰规则,并说明了如何通过`extern "C"`来关闭名字修饰。 8. **异常处理和栈展开**:异常处理涉及到在出现错误时如何恢复程序状态,而栈展开是异常处理的一部分,它用于回溯栈上的函数调用记录。 9. **初始化和终止**:这部分可能涉及程序启动时的初始化过程以及程序结束时的清理工作,这些操作可能受调用约定影响。 这份文档对理解跨平台的C++程序设计和编译器行为至关重要,对于开发人员来说,深入理解这些概念可以帮助编写更高效、兼容性更好的代码。

优化代码,加背景图import tkinter as tk import numpy as np def change_label(): button.destroy() label.config(text="请输入您的身高体重以及目标体重:") height_label.place(relx=0.5, rely=0.4, anchor="center") height_entry.place(relx=0.5, rely=0.45, anchor="center") weight_label.place(relx=0.5, rely=0.5, anchor="center") weight_entry.place(relx=0.5, rely=0.55, anchor="center") target_label.place(relx=0.5, rely=0.6, anchor="center") target_entry.place(relx=0.5, rely=0.65, anchor="center") submit_button.place(relx=0.5, rely=0.8, anchor="center") def show_buttons(): calculate_low_carb() calculate_medium_carb() calculate_high_carb() label.config(text="您的营养素分配如下:") label.place(relx=0.5, rely=0.2, anchor="center") height_label.destroy() height_entry.destroy() weight_label.destroy() weight_entry.destroy() target_label.destroy() target_entry.destroy() submit_button.destroy() submit_button_1.place(relx=0.5, rely=0.8, anchor="center") def calculate_low_carb(): global low_protein_intake, low_carb_intake, low_fat_intake height = float(height_entry.get()) weight = float(weight_entry.get()) target_weight = float(target_entry.get()) # 根据BMI计算蛋白质摄入量 bmi = weight / (height / 100)**2 if bmi >= 27: low_protein_intake = weight elif bmi >= 24 and bmi < 27: low_protein_intake = weight * 1.5 else: low_protein_intake = weight * 2 # 计算低碳日的碳水摄入量和脂肪摄入量 low_carb_intake = weight low_fat_intake = weight low_carb_label = tk.Label(root, text = "您低碳日的碳水摄入量为{:.1f}克,蛋白质摄入量为{:.1f}克,脂肪摄入量为{:.1f}克".format(low_carb_intake, low_protein_intake, low_fat_intake), font=("Arial", 18)) low_carb_label.place(relx=0.5, rely=0.4, anchor="center") def calculate_medium_carb(): global medium_protein_intake, medium_carb_intake, medium_fat_intake height = float(height_entry.get()) weight = float(weight_entry.get()) target_weight = float(target_entry.get()) # 根据BMI计算蛋白质摄入量 bmi = weight / (height / 100)**2 if bmi >= 27: medium_protein_intake = weight elif bmi >= 24 and bmi < 27: medium_protein_intake = weight * 1.5 else: medium_protein_intake = weight * 2 # 计算中碳日的碳水摄入量和脂肪摄入量 medium_carb_intake = weight * 2 medium_fat_intake = weight * 0.5 medium_carb_label = tk.Label(root, text = "您中碳日的碳水摄入量为{:.1f}克,蛋白质摄入量为{:.1f}克,脂肪摄入量为{:.1f}克".format(medium_carb_intake, medium_protein_intake, medium_fat_intake), font=("Arial", 18)) medium_carb_label.place(relx=0.5, rely=0.5, anchor="center")

2023-05-31 上传

import time import multiprocessing from proxypool.processors.server import app from proxypool.processors.getter import Getter from proxypool.processors.tester import Tester from proxypool.setting import CYCLE_GETTER, CYCLE_TESTER, API_HOST, API_THREADED, API_PORT, ENABLE_SERVER, \ ENABLE_GETTER, ENABLE_TESTER, IS_WINDOWS from loguru import logger if IS_WINDOWS: multiprocessing.freeze_support() tester_process, getter_process, server_process = None, None, None class Scheduler(): def run_tester(self, cycle=CYCLE_TESTER): if not ENABLE_TESTER: logger.info('tester not enabled, exit') return tester = Tester() loop = 0 while True: logger.debug(f'tester loop {loop} start...') tester.run() loop += 1 time.sleep(cycle) # CYCLE_GETTER=100 def run_getter(self, cycle=CYCLE_GETTER): if not ENABLE_GETTER: logger.info('getter not enabled, exit') return getter = Getter() loop = 0 while True: logger.debug(f'getter loop {loop} start...') getter.run() loop += 1 time.sleep(cycle) def run_server(self): if not ENABLE_SERVER: logger.info('server not enabled, exit') return app.run(host=API_HOST, port=API_PORT, threaded=API_THREADED) def run(self): global tester_process, getter_process, server_process try: logger.info('starting proxypool...') if ENABLE_TESTER: tester_process = multiprocessing.Process(target=self.run_tester) logger.info(f'starting tester, pid {tester_process.pid}...') tester_process.start() if ENABLE_GETTER: getter_process = multiprocessing.Process(target=self.run_getter) logger.info(f'starting getter, pid{getter_process.pid}...') getter_process.start() if ENABLE_SERVER: server_process = multiprocessing.Process(target=self.run_server) logger.info(f'starting server, pid{server_process.pid}...') server_process.start() tester_process.join() getter_process.join() server_process.join() except KeyboardInterrupt: logger.info('received keyboard interrupt signal') tester_process.terminate() getter_process.terminate() server_process.terminate() finally: # must call join method before calling is_alive tester_process.join() getter_process.join() server_process.join() logger.info(f'tester is {"alive" if tester_process.is_alive() else "dead"}') logger.info(f'getter is {"alive" if getter_process.is_alive() else "dead"}') logger.info(f'server is {"alive" if server_process.is_alive() else "dead"}') logger.info('proxy terminated') if name == 'main': scheduler = Scheduler() scheduler.run()给这段代码加注释

2023-06-09 上传
2023-06-07 上传

Calling tool in ralgen.py: /hpc/simulation/jzhou/awakening_soc/infra/flow/dv/tools/ralgen/../../../../util/regtool.py -s -t /tmp/mct_dv_bb_env-ral_0.1cvwdpui1 /hpc/simulation/jzhou/awakening_soc/design/bb/dv/env/../../data/bb.hjson RAL pkg for bb written to /tmp/mct_dv_bb_env-ral_0.1cvwdpui1. INFO: Wrote dependency graph to /hpc/simulation/jzhou/awakening_soc/scratch/default/gnss_top-sim-vcs/default/sim-vcs/mct_dv_bb_sim_0.1.deps-after-generators.dot WARNING: The file ../../include/yuu_ahb_interface.svi in /hpc/simulation/jzhou/awakening_soc/infra/verif/uvc/yuu_ahb/src/sv/ahb_env.core is not within the directory containing the core file. This is deprecated and will be an error in a future FuseSoC version. A typical solution is to move core file into the root directory of the IP block it describes WARNING: The file ../../include/yuu_ahb_pkg.sv in /hpc/simulation/jzhou/awakening_soc/infra/verif/uvc/yuu_ahb/src/sv/ahb_env.core is not within the directory containing the core file. This is deprecated and will be an error in a future FuseSoC version. A typical solution is to move core file into the root directory of the IP block it describes. WARNING: The file ../../test/ahb_base_seq.sv in /hpc/simulation/jzhou/awakening_soc/infra/verif/uvc/yuu_ahb/src/sv/ahb_env.core is not within the directory containing the core file. This is deprecated and will be an error in a future FuseSoC version. A typical solution is to move core file into the root directory of the IP block it describes. ERROR: Setup failed : Cannot find ../../test/ahb_base_seq.sv in : /hpc/simulation/jzhou/awakening_soc/infra/verif/uvc/yuu_ahb/src/sv

2023-07-20 上传