20240815阅读代码+业务实现

1. __int64 是什么数据类型?

今天看到一行代码

typedef unsigned __int64 uint_prt;

从未见过这种自带的数据类型,查之发现是win32平台专用的数据类型,它与64位的long long具体区别如下:

  1. long long定义方式可以用于gcc/g++,不受平台限制,但不能用于VC6.0。
  2. __int64是Win32平台编译器64位长整型的定义方式,不能用于Linux。

整数类型同义词

microsoft official docs link
编译器将以下类型组视为同义词:

  • short, short int, signed short, signed short int
  • unsigned short,unsigned short int
  • int, signed, signed int
  • unsigned,unsigned int
  • long, long int, signed long, signed long int
  • unsigned long,unsigned long int
  • long long, long long int, signed long long, signed long long int
  • unsigned long long,unsigned long long int

特定于 Microsoft 的整数类型包括特定宽度的 __int8、__int16、__int32 和 __int64 类型。 这些类型可以使用 signed 和 unsigned 修饰符。 __int8 数据类型与 char 类型同义,__int16 与 short 类型同义,__int32 与 int 类型同义,__int64 与 long long 类型同义。

2. 预处理指令#pragma+常见参数组合

在 C 语言中,#pragma 是一个预处理指令,通常用于向编译器提供特定的指示。不同的编译器支持的 #pragma 参数可能会有所不同,以下是一些常见的 #pragma 指令及其参数:

1. #pragma once

  • 用途: 防止头文件被多次包含。
  • 例子:
    #pragma once
    

2. #pragma pack

  • 用途: 控制结构体成员的对齐方式,常用于优化内存使用或匹配特定的硬件需求。
  • 例子:
    #pragma pack(push, 1)
    struct MyStruct {
        char c;
        int i;
    };
    #pragma pack(pop)
    
  • 解释: #pragma pack(push, 1) 将对齐方式设置为 1 字节对齐,#pragma pack(pop) 恢复之前的对齐设置。

3. #pragma warning

  • 用途: 用于控制编译器的警告信息。
  • 例子:
    #pragma warning(disable : 4996)
    
  • 解释: 禁用特定的警告(例如 4996 表示某个函数被标记为不安全)。

4. #pragma GCC diagnostic

  • 用途: 控制 GCC 编译器的诊断消息。
  • 例子:
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wunused-variable"
    int x;
    #pragma GCC diagnostic pop
    
  • 解释: 临时忽略 -Wunused-variable 警告。

5. #pragma region#pragma endregion

  • 用途: 在代码中定义折叠区域,通常用于更好地组织代码。
  • 例子:
    #pragma region MyRegion
    // code...
    #pragma endregion
    

6. #pragma message

  • 用途: 在编译时输出自定义消息,常用于调试。
  • 例子:
    #pragma message("Compiling " __FILE__)
    

7. #pragma omp

  • 用途: 用于并行编程,支持 OpenMP 标准。
  • 例子:
    #pragma omp parallel for
    for (int i = 0; i < n; ++i) {
        // parallel loop
    }
    

8. #pragma comment

  • 用途: 用于向链接器传递特定的命令,主要用于 MSVC 编译器。
  • 例子:
    #pragma comment(lib, "user32.lib")
    
  • 解释: 自动链接 user32.lib 库。

9. #pragma inline

  • 用途: 控制内联函数的生成,特定于某些编译器(如 MSVC)。
  • 例子:
    #pragma inline_recursion(on)
    
  • 解释: 启用递归内联。

10. #pragma optimize

  • 用途: 控制编译器优化设置,特定于 MSVC 编译器。
  • 例子:
    #pragma optimize("", off)
    
  • 解释: 禁用优化。

注意事项

  • 并非所有编译器都支持相同的 #pragma 参数,因此在编写跨平台代码时,需注意特定编译器的兼容性。
  • 不同的编译器对 #pragma 的支持和实现方式有所不同,因此最好参考编译器的文档。

3. 控制结构体对齐的好处

控制结构体成员的对齐在编程中有多个用途,主要包括内存优化、性能提升以及硬件兼容性等方面。以下是一些主要原因和用途:

1. 内存对齐与内存优化

  • 对齐的定义: 在计算机中,内存通常以字节(byte)为单位存储数据。为了提高访问效率,通常要求某些数据类型在内存中按照特定的字节边界(例如 4 字节或 8 字节边界)对齐,这就叫做内存对齐。
  • 节省内存: 默认情况下,编译器会对结构体中的成员按其自然对齐要求进行对齐,这可能会在成员之间插入额外的填充字节(padding)。通过使用 #pragma pack 指令,开发者可以强制编译器使用更紧密的对齐方式,从而减少填充字节的使用,节省内存。
  • 例子:
    #pragma pack(push, 1)
    struct PackedStruct {
        char c;
        int i;
    };
    #pragma pack(pop)
    
    在这个例子中,由于使用了 1 字节对齐,int 类型成员 i 将直接跟在 char 类型成员 c 之后,不会有额外的填充字节,从而减少了结构体的总大小。

2. 硬件兼容性

  • 硬件要求: 某些硬件平台(尤其是嵌入式系统)对数据对齐有严格要求。如果数据没有按预期对齐,可能会导致硬件异常或性能下降。在这些场景下,控制结构体对齐是确保代码在特定硬件上正确运行的必要条件。
  • 外部数据格式: 在与外部系统(例如网络协议、文件格式)进行数据交互时,常常需要按照特定的对齐方式来排列数据,以确保数据能够正确解析和传输。

举个例子

#include <stdio.h>

struct DefaultAlign {
    char c;
    int i;
};

#pragma pack(push, 1)
struct PackedAlign {
    char c;
    int i;
};
#pragma pack(pop)

int main() {
    printf("Size of DefaultAlign: %zu bytes\n", sizeof(struct DefaultAlign)); // 通常是 8
    printf("Size of PackedAlign: %zu bytes\n", sizeof(struct PackedAlign));   // 通常是 5
    return 0;
}
  • DefaultAlign 结构体由于默认对齐规则,会在 charint 之间插入填充字节,大小可能为 8 字节。
  • PackedAlign 结构体强制为 1 字节对齐,大小为 5 字节,没有填充字节。

4. extern C

reference link
【废话】在一个项目中,能否既包含 C++ 程序又包含 C 程序呢?换句话说,C++ 和 C 可以进行混合编程吗?要知道,在 C++ 出现之前,很多实用的功能都是用 C 语言开发的,很多底层的库也是用 C 语言编写的。这意味着,如果能在 C++ 代码中兼容 C 语言代码,无疑能极大地提高 C++ 程序员的开发效率。幸运的是,C++ 给出了相应的解决方案,即借助 extern “C”,就可以轻松解决 C++ 和 C 在处理代码方式上的差异性。

extern “C” 既可以修饰一句 C++ 代码,也可以修饰一段 C++ 代码,它的功能是让编译器以处理 C 语言代码的方式来处理修饰的 C++ 代码。

#ifdef __cplusplus
extern "C" void display();
#else
void display();
#endif

#ifdef __cplusplus
extern "C" {
#endif

void display();

#ifdef __cplusplus
}
#endif

概念我是知道,但需要记住的是下面的代码写法,相信这在以后阅读代码时会挺常见的…

5. 灌包

灌包(Padding)在无线通信中常见的有上行灌包、下行灌包(Downlink Padding)。灌包的应用主要是为了满足特定的协议要求、传输格式或者提高资源利用率。具体做法就是向链路的数据包中填充一些没用的数据,来满足一些要求。

灌包作为链路传输的连续性和资源利用的一种技术手段,虽然它并不直接传输有用的用户数据,但对于维持网络性能和满足协议要求具有重要作用。下面我们探讨不同类型的灌包以及它们的作用。

1. 上行灌包

在无线通信中,“上行灌包”指的是在上行链路(UE到基站的通信方向)中,用户设备(UE)向基站发送大量数据包的行为。具体来说,上行灌包(Uplink Padding)在无线网络中的一些特定场景下应用,例如在MAC层或RLC层,为了确保数据的连续传输或者满足特定的协议要求,系统需要填充或补足数据包的大小,这些填充的数据被称为“灌包”。

上行灌包的具体应用场景:
  1. 保持传输时隙的利用

    • 在一些无线通信协议中,为了利用上行链路的所有可用资源,系统可能需要在没有足够的数据负载时进行“灌包”来填满传输时隙。这可以避免浪费带宽并保持系统效率。
  2. 确保数据包大小的一致性

    • 在某些情况下,协议要求数据包的大小必须是特定的,比如固定大小的传输块(Transport Block)。如果实际的数据量不足,系统就需要通过“灌包”来填充这些空余的部分,确保数据包达到规定的大小。
  3. 协议要求

    • 在无线通信协议中,例如LTE或5G NR,为了适应特定的传输模式或技术要求(如HARQ、调度策略等),上行灌包可能被用来满足特定的帧结构或传输格式。
上行灌包的影响:
  • 网络资源利用:上行灌包可以提高传输资源的利用率,但同时也可能导致系统传输一些无用的数据,从而增加了系统的负担。
  • 数据处理:基站需要能够识别并处理这些灌包数据,以确保它们不会对有效载荷造成干扰。

2. 下行灌包(Downlink Padding)

  • 定义:下行灌包是在下行链路(基站到用户设备的方向)中,基站在发送数据时可能会在数据包中添加填充数据,以确保传输块的大小或格式符合协议要求。
  • 应用场景
    • 信令消息传输:有时下行链路中需要传输的信令数据较少,而传输块的大小是固定的,基站可能会填充无用的数据来满足这个固定大小的要求。
    • 维持传输时隙利用率:在多用户共享信道的场景下,基站可能会填充数据以确保在分配的时隙中最大化数据传输,避免资源浪费。

3. 对于灌包的疑问

灌包对传输资源利用率的影响?

灌包之所以能够提高传输资源的利用率,是因为在无线通信系统中,传输资源是以时隙、频带或者信道为单位分配的。为了确保这些资源在分配给用户后得到充分利用,灌包技术被用来填充未被实际数据利用的资源。这种填充虽然是无用的数据,但它确保了信道的利用率。

<<<举个例子>>>

假设我们正在发送邮件,但这不是普通的邮件,而是用“传输块”来传递邮件的内容。这个传输块的容量是固定的,比如我们只能用一个固定大小的信封(传输块),每个信封都必须装满1024字节的内容,无论信封里装的是真正的邮件内容(有用数据)还是空白纸(灌包数据)。

现在,你需要给朋友发一封只有900字节的邮件(有用数据),但由于信封的规定,你必须把信封装满1024字节。剩下的124字节怎么办呢?你不能留空,因为规定信封必须装满。所以你选择在剩下的地方放上一些空白纸(灌包数据)来填满信封。

那为什么这样做能避免资源浪费呢?假设你没有填充这个124字节的空白纸,而是选择不发送这一部分。结果会是什么?在网络中,每一个传输块(信封)是一个独立的资源,系统已经为你分配了1024字节的带宽(信封的容量),如果你不把它用满,那么系统就会浪费掉这个剩余的124字节,因为这个未使用的部分不能被重新分配给其他用户。就好比邮局已经为你准备好了一个1024字节容量的信封,但是你只用了900字节,剩下的124字节空着被浪费掉。所以,通过填充这124字节的“无用数据”(空白纸),你确保了整个1024字节的传输块(信封)都被充分利用,系统也就没有浪费分配给你的资源。

简言之,给你用你就用完,用不完就属于浪费!但有人就要问了,早知道你用不完,上层为什么要规定这么大的传输块?这其实就是一个调度问题了,基站不可能面面俱到给每个UE都提供精确到家的服务,这个传输块的大小是它综合考量各种因素才得出的值,对于无线通信系统整体来说它是接近最优解的。但虽说如此,说不灌包浪费我还是觉得有点不乐意的\doge。

灌包避免浪费带宽的原因
  • 在无线通信中,带宽和时间资源是被严格分配的。每个传输时隙或信道都有一个固定的容量,若不利用灌包技术,则未使用的部分可能无法再次利用,造成资源浪费。
  • 资源调度的挑战:在复杂的多用户环境中,实时调度每个用户的资源是一项挑战。灌包确保了即使在数据量不足的情况下,已分配的资源仍然可以被占满,防止频繁的调度调整和资源碎片化,这对于保持高效的传输和稳定的网络性能至关重要。
无用数据的传输是否浪费?

这也算是回答了我的疑问,灌包虽然灌的是无用数据,但它利大于弊!

  • 相对浪费与效率:虽然灌包传输的是无用的数据,但在无线通信的复杂环境中,这些填充数据带来的好处往往超过其引入的开销。例如,通过灌包保证传输时隙的完整利用,可以避免频繁的调度切换,从而降低调度延迟和复杂性,提高系统整体的传输效率。
  • 协议要求:有时协议规定数据包的结构或大小,因此必须遵循这些规则来确保设备之间的兼容性和通信的稳定性。灌包正是为了满足这些技术要求而存在的。

6. NSA和SA概念

NSA(Non-Standalone)和SA(Standalone)是5G网络架构中的两种主要部署模式。这两种架构各有优缺点,运营商通常会根据自身网络现状和未来发展策略选择适合的部署模式。在实际应用中,NSA模式常用于初期5G网络的快速部署,而SA模式是5G网络发展的长远目标。

简单理解就是NSA模式适用于5G的快速部署阶段,它利用现有的4G基础设施来提供5G服务。而SA模式则代表了完全成熟的5G网络,能够提供5G的全部功能和优势,是未来5G网络的最终目标。

1. NSA(Non-Standalone):

  • 定义:NSA是一种混合网络架构,在这种模式下,5G网络依赖于现有的4G LTE网络基础设施。5G NR(New Radio)被用作一个增强层,与现有的4G LTE网络协同工作,来提供更高的数据传输速度和更好的网络性能。
  • 特点
    • 依赖4G核心网:在NSA模式下,5G基站依然连接到4G核心网(EPC,Evolved Packet Core)。也就是说,5G NR的控制信令是通过4G LTE来管理的,5G只负责提供数据承载。
    • 快速部署:因为可以利用现有的4G基础设施,NSA模式可以更快速、更经济地部署5G网络。
    • 过渡阶段:NSA模式通常被视为向完全5G SA网络过渡的一个中间阶段,运营商可以在这一模式下提供部分5G服务,同时逐步升级核心网络。

2. SA(Standalone):

  • 定义:SA是一种纯5G网络架构,完全独立于4G网络运作。它使用5G NR作为唯一的接入网络,并且连接到5G核心网(5GC, 5G Core)。
  • 特点
    • 独立的5G核心网:SA模式不依赖4G网络,5G的控制信令和数据承载全部通过5G网络进行。
    • 完整的5G特性:SA模式能够提供5G的全部特性和功能,包括超低延迟、网络切片(Network Slicing)、增强的移动宽带(eMBB)、超可靠低时延通信(URLLC)和大规模机器类通信(mMTC)。
    • 更高的网络性能:由于完全使用5G的架构,SA模式可以实现更高的网络性能、更低的延迟和更灵活的服务质量控制。

7. 切换handover

Handover(切换)是无线通信网络中一个重要的过程,它指的是用户设备(UE)在移动过程中,从一个基站切换到另一个基站的过程,以保持连接的连续性和稳定性。切换过程需要确保通信的不中断,同时尽量减少服务质量的影响。下面我们详细讨论handover的分类和具体的技术细节。

Handover的分类

根据不同的标准,切换可以分为多种情况,主要包括以下几种分类方式:

1. 按切换的方向分类
  • 水平切换(Horizontal Handover):在同一网络类型之间进行的切换,比如在同一LTE网络的不同基站之间进行切换。这是最常见的切换类型。
  • 垂直切换(Vertical Handover):在不同网络类型之间进行的切换,例如从4G LTE网络切换到Wi-Fi,或者从3G切换到4G。
2. 按切换的触发条件分类
  • 硬切换(Hard Handover):也称为“断点切换”,是指在切换过程中,用户设备先断开与原基站的连接,然后再连接到新基站。硬切换通常发生在资源受限的环境下,是一种“先断后连”的过程。缺点是切换过程中可能会出现短暂的通信中断。
  • 软切换(Soft Handover):用户设备在切换过程中同时与多个基站保持连接,直到确认新的连接稳定之后,才断开与旧基站的连接。软切换常见于CDMA网络中,可以减少通信中断的风险。
  • 更软切换(Softer Handover):这是软切换的一种特殊情况,发生在同一基站的不同扇区之间。用户设备与同一基站的多个扇区同时连接,从而保持更高的信号强度和连接质量。

Handover的详细技术细节

  1. 测量报告(Measurement Report)

    • 用户设备在连接过程中会定期测量其周围基站的信号强度、信噪比、邻区信息等,并将这些信息上报给当前连接的基站。这些测量报告是网络决定何时进行切换的重要依据。
  2. 切换决策(Handover Decision)

    • 基站或核心网络根据测量报告、用户位置、网络负载等因素来决定是否进行切换,以及目标基站是哪一个。切换的触发可以是信号强度下降到一定阈值,或者目标基站信号变得更好等。
  3. 切换命令(Handover Command)

    • 一旦切换决策做出,网络会向用户设备发送切换命令,通知用户设备即将切换到新的基站或扇区。命令中会包含目标基站的识别信息、频段信息等。
  4. 切换执行(Handover Execution)

    • 用户设备收到切换命令后,按照命令中指定的目标基站进行切换。切换的过程包括重新同步新的基站、切换无线链路、重新获取上下行信道等步骤。
  5. 切换确认(Handover Completion)

    • 用户设备成功连接到目标基站后,会发送切换完成确认消息。如果是硬切换,旧基站会释放相关资源;如果是软切换,用户设备会断开与旧基站的连接。
  6. 失败处理(Handover Failure Handling)

    • 如果切换过程失败(例如用户设备未能成功连接到目标基站),系统会触发切换恢复机制。通常用户设备会重新连接到原基站,或者重新发起新的切换过程。

特殊情况和优化措施

  • Ping-Pong Effect(乒乓效应)

    • 乒乓效应是指用户设备在两个基站之间频繁切换,通常发生在两个信号强度非常接近的基站边界区域。这种频繁切换会导致资源浪费和通信不稳定。为避免乒乓效应,网络可以通过调整切换触发阈值、增加切换滞后时间等方式进行优化。
  • Load Balancing(负载均衡)

    • 在高密度用户区域,某些基站可能会出现过载现象。网络可以通过切换机制将用户设备切换到负载较轻的基站,以实现负载均衡,提高整体网络性能。
  • Inter-RAT Handover(异制式切换)

    • 这种切换发生在不同无线接入技术之间,例如从4G LTE切换到5G NR,或者从LTE切换到Wi-Fi。异制式切换通常涉及到更复杂的信令和协议转换,以确保用户设备在不同网络之间无缝切换。

上面只是对切换handover进行了简单介绍,如果想要了解更加详细的细节的话,可以先查看以下两篇文章。

5G切换流程详细介绍
5G 切换(handover)那点事儿

8. 关于上面那篇文章提到的不同的切换类型

GPT如是解释…不得不说专用大模型就是好用!!!

在无线通信网络中,切换(Handover)是确保用户设备在移动过程中保持连续连接的重要机制。你提到的几种切换类型——盲切(Blind Handover)、基于覆盖范围的同频切换(Coverage Based Intra-Frequency Handover)、基于覆盖范围的异频切换(Coverage Based Inter-Frequency Handover)、以及基于频段优先级的异频切换(Frequency Priority Based Inter-Frequency Handover)——各自有其特定的应用场景和技术特点。下面我来详细介绍这些切换类型。

1. 盲切(Blind Handover)

盲切,也称为无测量切换,是一种在切换前无需进行信号测量的切换方式。在这种切换中,网络预先根据已知的条件或策略决定切换到哪个目标小区或基站,而不依赖于实时的测量报告。

应用场景

  • 适用于网络对目标小区或基站的覆盖范围和性能有充分了解,或在某些特殊场景下,如快速切换或无信号覆盖的区域(例如从地铁隧道进入地面时),盲切可以避免信号测量带来的延迟。
  • 这种切换方式通常用于特殊情况,如当用户设备正在进入一个网络覆盖边缘或切换到一个预定义的目标小区时。

优点

  • 切换过程简化,速度较快,因为省去了信号测量和上报的步骤。
  • 有助于应对特殊场景下的快速切换需求。

缺点

  • 由于没有实时的信号测量数据,可能导致切换到信号质量较差的小区,增加切换失败的风险。

2. 基于覆盖范围的同频切换(Coverage Based Intra-Frequency Handover)

基于覆盖范围的同频切换,是指在同一频段内,根据用户设备的信号覆盖情况进行切换。这种切换通常在同一个无线接入技术(RAT)中进行,并且发生在使用相同频段的两个相邻小区之间。

应用场景

  • 主要应用于用户设备在同一频段覆盖范围内从一个小区移动到另一个小区的情况。
  • 这种切换常见于蜂窝网络中的宏小区切换,或者在密集部署的小区网络中进行微小区切换。

优点

  • 由于在同一频段内切换,切换过程中的频率重选等复杂步骤可以省略,减少了切换延迟。
  • 有助于维护用户设备的稳定连接,特别是在高移动性的场景中。

缺点

  • 同频干扰可能会影响切换的质量,特别是在频谱资源有限的情况下。

3. 基于覆盖范围的异频切换(Coverage Based Inter-Frequency Handover)

基于覆盖范围的异频切换,是指根据用户设备的信号覆盖情况,在不同频段之间进行切换。这种切换通常在同一无线接入技术(RAT)中,但频段不同的两个相邻小区之间进行。

应用场景

  • 当用户设备从一个频段的覆盖区域移动到另一个频段覆盖区域时,例如从低频段的宏小区覆盖区进入高频段的微小区覆盖区,或反之亦然。
  • 在多频段网络中,用于优化覆盖和容量,以确保用户设备始终处于最佳的覆盖条件下。

优点

  • 通过利用不同频段的特性,可以优化网络的覆盖范围和容量分配。例如,低频段用于广覆盖,高频段用于高容量需求的区域。
  • 有助于负载均衡,缓解某个频段的过载情况。

缺点

  • 由于涉及不同频段的切换,切换过程较为复杂,可能需要进行频率重选和信道再分配,增加了切换的延迟和失败的风险。

4. 基于频段优先级的异频切换(Frequency Priority Based Inter-Frequency Handover)

基于频段优先级的异频切换,是指根据网络中不同频段的优先级策略来决定用户设备在不同频段之间的切换。网络会根据预定义的频段优先级,将用户设备切换到优先级更高的频段。

应用场景

  • 当网络部署了多个频段,并且希望引导用户设备使用特定频段(例如新部署的高频段)以提高整体网络性能时,会使用这种切换策略。
  • 适用于优化频谱利用率、提高高优先级频段的使用率或转移低优先级频段的负载。

优点

  • 通过优先级策略,网络可以主动管理频谱资源分配,提升网络效率。
  • 有助于实现新频段的快速利用,特别是在新频段初期部署阶段。

缺点

  • 如果优先级策略不当,可能会导致高优先级频段过载或低优先级频段资源浪费。
  • 频繁的异频切换可能会增加切换失败率和通信中断的风险。

总结

这些切换机制在无线通信网络中发挥着不同的作用,根据网络部署情况和业务需求来选择合适的切换方式,可以有效地提升网络性能和用户体验。盲切适用于特定场景的快速切换,而基于覆盖范围和频段优先级的切换则更适合常规的网络优化需求。

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值