Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用uint64\t的不便之处_C_Performance_Embedded_Portability_Uint64 - Fatal编程技术网

C 使用uint64\t的不便之处

C 使用uint64\t的不便之处,c,performance,embedded,portability,uint64,C,Performance,Embedded,Portability,Uint64,我有一个高度可移植的库(它在任何地方都可以编译并运行良好,即使没有内核),我希望它尽可能保持可移植性。到目前为止,我已经避免使用64位数据类型,但我现在可能需要使用它们——确切地说,我需要一个64位位掩码 我从来没有真正考虑过这一点,而且我还不够精通硬件(特别是在嵌入式系统方面),但我现在想知道:使用uint64\u t(或者,等效地说,uint\u t)有什么不便之处?我可以想出两种方法来回答我的问题: 实际可移植性:所有微控制器——包括8位CPU——都能处理64位整数吗 性能:与32位整数相

我有一个高度可移植的库(它在任何地方都可以编译并运行良好,即使没有内核),我希望它尽可能保持可移植性。到目前为止,我已经避免使用64位数据类型,但我现在可能需要使用它们——确切地说,我需要一个64位位掩码

我从来没有真正考虑过这一点,而且我还不够精通硬件(特别是在嵌入式系统方面),但我现在想知道:使用
uint64\u t
(或者,等效地说,
uint\u t
)有什么不便之处?我可以想出两种方法来回答我的问题:

  • 实际可移植性:所有微控制器——包括8位CPU——都能处理64位整数吗
  • 性能:与32位整数相比,8位CPU对64位整数执行逐位运算的速度有多慢?我正在设计的函数只有一个64位变量,但会对其执行许多位操作(即在循环中)

  • 对合格的C编译器有各种最低要求。C语言允许两种形式的编译器:托管编译器和独立编译器。Hosted是指在操作系统上运行,而独立运行则不需要操作系统。大多数嵌入式系统编译器都是独立的实现

    独立编译器有一定的回旋余地,它们不需要支持所有标准库,但需要支持它们的最小子集。这包括
    stdint.h
    (参见C17 4/6)。这反过来要求编译器实现以下内容(C17.20.1.2/3):

    以下类型是必需的:

    至少8分钟 至少16分钟 至少32分钟 至少内部64\u t
    至少8 至少16分钟 至少32分钟 至少有64个

    因此,微控制器编译器不需要支持
    uint64\u t
    ,但它必须(奇怪的是)支持
    uint64\u t
    。实际上,这意味着编译器也可以添加
    uint64\t
    支持,因为在本例中也是这样

    至于8位MCU支持什么。。。它通过指令集支持8位算术运算,在某些特殊情况下还支持使用索引寄存器的一些16位运算。但一般来说,只要使用大于8位的类型,它就必须依赖软件库

    因此,如果您在8位处理器上尝试32位算术,它会将一些编译器软件库与代码内联,结果将是数百条汇编指令,这使得此类代码非常低效且占用内存。64位将更糟糕

    对于缺少FPU的MCU上的浮点数,同样的事情也会通过软件浮点数库生成效率极低的代码


    为了说明这一点,我们来看一下8-AVR(gcc)上一些非常简单的64位加法的非优化代码:
    它实际上支持
    uint64\u t
    ,但编译器输出了大量开销代码,大约100条指令。在中间,调用一个内部编译器函数<代码>调用*AddiD3隐藏在可执行文件中。 如果我们启用优化,我们将得到

    add64:
            push r10
            push r11
            push r12
            push r13
            push r14
            push r15
            push r16
            push r17
            call __adddi3
            pop r17
            pop r16
            pop r15
            pop r14
            pop r13
            pop r12
            pop r11
            pop r10
            ret
    
    我们必须通过挖掘库源代码或程序集的单步运行来查看
    \uuu adddi3
    中有多少代码。我想这仍然不是一个简单的函数


    正如你所希望的,在一个8位CPU上做64位运算是一个很坏的想法。

    嗯,如果你的首要关注点是保持一个公平的兼容性级别,这就是避免使用64位数字的原因,为什么不使用一个数组< <代码> int >代码>整数,并考虑使用一个完整的整数来存储,比如说,30位

    我建议您查看有关使用位掩码(大于32位)表示(例如,
    select(2)
    系统调用接触的文件)的标准库源,以及如何使用
    FDSET

    正确的情况是,您可能有一个问题,即决定是否在用于表示位图的数据类型中超过32位的限制,或者(暂时)使用仍然可用的64位类型来解决问题。这将是下一个规模的问题,当你得到大约64位位的位掩码,你将最终不得不越过这条线

    作为练习,您现在就可以这样做,您将了解到最后的数据类型或多或少是一组较大的位,您可以根据需要使用它们。您是否计划使用80位
    长双精度
    值来存储大于64位的位掩码?我想你不会的,所以想想阵列解决方案,它可能会永远解决你的问题

    如果你的问题是我的情况,我会写一个32位无符号数的数组,这样所有的位在移位、位运算等方面都表现相同

    
    #define FDSET_TYPE(name, N)  unsigned int name[((N) + 31U) >> 5]
    #define FDSET_ISSET(name, N) ((name[(N) >> 5] & 1 << (N & 0x1f)) != 0)
    
    ...
    
        FDSET_TYPE(name, 126);
    
    ...
    
        if (FDSET_ISSET(name, 35)) { ...
    
    
    #定义FDSET_类型(名称,N)无符号整数名称[((N)+31U)>>5]
    
    #定义FDSET_ISSET(名称,N)((名称[(N)>>5]&1 8位CPU始终能够处理多字节算术和位操作,但效率不是很高。64位的执行时间通常是32位的两倍,但如下所述,可以免费检查或设置/清除内存中的单个位。即使8位CPU也可以处理64位值。按位操作通常是优化良好。在8位CPU上,检查单个标志通常与检查2 32位或4 16位值上的单个标志一样快。我使用标准的64位类型,让编译器计算出来。这是一样的。只需为所有需要的操作定义一组宏/函数(setbit、getbit、clearbit,可能是mask)并使用这些。一旦你意识到你实际上需要超过64位,或者你的机器不提供64位,这将有助于你。@madmurphy将位掩码拆分为2,如果你能形成比编译器更好的代码。否则,请相信你的编译器和代码的清晰性。使用比这更高级别的代码可以节省你的宝贵时间好的,回答得很好。不过,请注意