相关疑难解决方法(0)

C数据类型如何"大多数计算机直接支持"?

我正在阅读K&R的"The C Programming Language"并且发现了这个声明[Introduction,p.3]:

由于大多数计算机都直接支持C提供的数据类型和控制结构,因此实现自包含程序所需的运行时库很小.

粗体陈述是什么意思?是否存在计算机直接支持的数据类型或控制结构的示例?

c

114
推荐指数
7
解决办法
7189
查看次数

C++中循环移位(旋转)操作的最佳实践

左右移位运算符(<<和>>)已在C++中可用.但是,我无法找到如何执行循环移位或旋转操作.

如何执行"向左旋转"和"向右旋转"等操作?

在这里向右旋转两次

Initial --> 1000 0011 0100 0010
Run Code Online (Sandbox Code Playgroud)

应该导致:

Final   --> 1010 0000 1101 0000
Run Code Online (Sandbox Code Playgroud)

一个例子会有所帮助.

(编者注:如果旋转计数为零,许多常见的表达方式在C中旋转会受到未定义的行为的影响,或者编译为不止一个旋转机器指令.这个问题的答案应记录最佳实践.)

c c++ bit-manipulation c++-faq rotation

84
推荐指数
9
解决办法
10万
查看次数

装配ADC(随附进位)到C++

有汇编指令ADC.我发现这意味着"随身携带".但我不知道意味着什么.或者如何用C++编写这个指令.我知道它不一样ADD.所以做一个简单的求和是不正确的.

信息:
在Windows中编译.我正在使用32位Windows安装.我的处理器是Intel的Core 2 Duo.

c++ x86 assembly

16
推荐指数
5
解决办法
3万
查看次数

使用进位标志添加多字

GCC具有128位整数.使用这些我可以让编译器使用mul(或imul只有一个操作数)指令.例如

uint64_t x,y;
unsigned __int128 z = (unsigned __int128)x*y;
Run Code Online (Sandbox Code Playgroud)

生产mul.我用它来创建一个128x128到256的函数(在更新之前,请参阅此问题的结尾,如果您感兴趣,请参阅此代码).

现在我想要进行256位加法,ADC除了使用汇编之外,我还没有找到让编译器使用的方法.我可以使用汇编程序,但我想要内联函数以提高效率.编译器已经生成了一个有效的128x128到256函数(因为我在这个问题的开头解释了)所以我不明白为什么我应该在汇编中重写它(或者编译器已经有效实现的任何其他函数) .

这是我提出的内联汇编函数:

#define ADD256(X1, X2, X3, X4, Y1, Y2, Y3, Y4) \
 __asm__ __volatile__ ( \
 "addq %[v1], %[u1] \n" \
 "adcq %[v2], %[u2] \n" \
 "adcq %[v3], %[u3] \n" \
 "adcq %[v4], %[u4] \n" \
 : [u1] "+&r" (X1), [u2] "+&r" (X2), [u3] "+&r" (X3), [u4] "+&r" (X4) \
 : [v1]  "r" (Y1), [v2]  "r" (Y2), [v3]  "r" (Y3), [v4] …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly gcc visual-c++

13
推荐指数
1
解决办法
2124
查看次数

试验部门对素性的条件测试

我的问题是关于试验部门的条件测试.关于采用什么条件测试似乎存在争议.我们来看看RosettaCode的代码 .

int is_prime(unsigned int n)
{
    unsigned int p;
    if (!(n & 1) || n < 2 ) return n == 2;

    /* comparing p*p <= n can overflow */
    for (p = 3; p <= n/p; p += 2)
        if (!(n % p)) return 0;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

车轮分解或使用预定的素数列表不会改变我的问题的本质.

我可以想到三种情况来进行条件测试:

  1. P <= N/P
  2. P*P <= N
  3. int cut = sqrt(n); for(p = 3; p <= cut; p + = 2)

案例1:适用于所有n但它必须在每次迭代时进行额外的除法(编辑:实际上它不需要额外的除法但它仍然较慢.我不知道为什么.请参阅下面的汇编输出).我发现它的速度是情况2的两倍,因为大的n值是素数(在我的Sandy Bridge系统上).

案例2:明显快于案例1,但它有一个问题,它溢出大n并进入一个不定式循环.它可以处理的最大值是

(sqrt(n) …
Run Code Online (Sandbox Code Playgroud)

c math floating-point primes

8
推荐指数
1
解决办法
765
查看次数

Visual C++ x64附带进位

因为似乎没有ADC的固有内容而且我不能使用Visual C++的x64架构使用内联汇编程序,如果我想使用add with carry编写函数但是将它包含在C++命名空间中,我该怎么办?

(使用比较运算符进行仿真不是一种选择.这256兆位的添加对性能至关重要.)

c++ 64-bit inline-assembly intrinsics visual-c++

7
推荐指数
2
解决办法
2682
查看次数

_addcarry_u64和_addcarryx_u64与MSVC和ICC

MSVC和ICC都支持内在函数_addcarry_u64_addcarryx_u64.

根据英特尔的内在指南白皮书,这些应分别映射到adcxadox.但是,通过查看生成的程序集,很明显它们分别映射到adc并且adcx没有映射到的内在函数adox.

另外,告诉编译器/arch:AVX2MSVC中启用AVX2 或-march=core-avx2在Linux上启用ICC没有任何区别. 我不确定如何使用MSVC和ICC启用ADX.

MSVC文档列出_addcarryx_u64了ADX技术,_addcarry_u64但没有列出的技术.但是,MSVC针对这些内在函数的文档中的链接直接指向Intel Intrinsic指南,该指南与MSVC自己的文档和生成的程序集相矛盾.

由此我得出结论,英特尔的内在指南和白皮书是错误的.

这对于MSVC感觉有一定意义,它不允许内联汇编它应该提供一种使用adc它的方式_addcarry_u64.

其中的一大优点adcx,并adox为他们在不同的标志(进操作CF和溢出OF),这使得两个独立平行进位链.但是,由于没有内在的adox可能性如何?对于ICC,至少有一个可以使用内联汇编,但在64位模式下使用MSVC是不可能的.


微软和英特尔的文档(白皮书和在线内在指南)都同意了.

_addcarry_u64征的文件说只生产adc.该_addcarryx_u64征可以产生两种adcxadox.然而,在MSVC 2013和2015中,_addcarryx_u64只生产adcx.ICC同时生产.

assembly icc intrinsics visual-c++ adx

7
推荐指数
2
解决办法
1332
查看次数

在 C++ 中进行基本 128 位整数计算的有效方法?

几年前,我需要一种方法来使用 Cuda 进行一些基本的 128 位整数数学运算: cuda 上的 128 位整数?. 现在我遇到了同样的问题,但这次我需要在不支持任何类型的 128 位的 32 位嵌入式系统(英特尔爱迪生)上运行一些基本的 128 位算术(求和、位移和乘法)。但是,有直接支持的 64 位整数(unsigned long long int)。

我天真地尝试使用上次在CPU上回答我的asm代码,但是我得到了一堆错误。我真的没有使用 asm 的经验,所以:使用 64 位整数实现 128 位加法、乘法和位移的最有效方法是什么?

c++ x86 assembly int128 intel-edison

4
推荐指数
2
解决办法
7656
查看次数

是否存在用于C中的add-with-carry的ARM内在函数?

是否存在ARM C编译器的内在函数来执行随身携带操作,或者是否需要使用汇编语言?

在x86上,有_addcarry_u64for-carry-carry.(_addcarryx_u64特殊目的还有更新的.)

arm intrinsics

4
推荐指数
1
解决办法
443
查看次数