相关疑难解决方法(0)

为什么GCC在实现整数除法时使用乘以奇数的乘法?

我一直在阅读divmul组装操作,我决定通过在C中编写一个简单的程序来实现它们:

文件分割

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后生成汇编语言代码:

gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)

但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:

mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 integer-division

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

C/C#的模量越快?

对于特定碱基,是否有创建比标准%运算符更快的整数模数的技巧?

对于我的程序,我会寻找大约1000-4000(例如n%2048).有没有以执行N模量2048不仅仅是一个更快的方法:n%2048

c# math optimization modulus

20
推荐指数
2
解决办法
1万
查看次数

为什么32字节的循环对齐使代码更快?

看看这段代码:

one.cpp:

bool test(int a, int b, int c, int d);

int main() {
        volatile int va = 1;
        volatile int vb = 2;
        volatile int vc = 3;
        volatile int vd = 4;

        int a = va;
        int b = vb;
        int c = vc;
        int d = vd;

        int s = 0;
        __asm__("nop"); __asm__("nop"); __asm__("nop"); __asm__("nop");
        __asm__("nop"); __asm__("nop"); __asm__("nop"); __asm__("nop");
        __asm__("nop"); __asm__("nop"); __asm__("nop"); __asm__("nop");
        __asm__("nop"); __asm__("nop"); __asm__("nop"); __asm__("nop");
        for (int i=0; i<2000000000; i++) {
                s += test(a, b, …
Run Code Online (Sandbox Code Playgroud)

performance benchmarking gcc x86-64 clang

12
推荐指数
1
解决办法
735
查看次数

在64位机器上,我可以安全地并行操作64位四字的单个字节吗?

背景

我正在对图像中的行和列进行并行操作.我的图像是8位或16位像素,我在64位机器上.当我对并行的列进行操作时,两个相邻的列可以共享相同的32位int或64位long.基本上,我想知道我是否可以安全地并行操作同一个四字的单个字节.

最小的测试

我写了一个我无法失败的最小测试函数.对于64位中的每个字节long,我同时在有限的有序域中执行连续的乘法p.我知道费马的小定理 a^(p-1) = 1 mod p何时p是素数.我改变了值ap我的8个线程中的每一个,并执行k*(p-1)乘法运算a.当线程完成每个字节应该是1.事实上,我的测试用例通过了.每次运行时,我都会得到以下输出:

8
101010101010101
101010101010101

我的系统是Linux 4.13.0-041300-generic x86_64,带有8核Intel(R)Core(TM)i7-7700HQ CPU @ 2.80GHz.我用g ++ 7.2.0 -O2编译并检查了程序集.我添加了"INNER LOOP"的程序集并对其进行了评论.在我看来,生成的代码是安全的,因为存储只是将低8位写入目标而不是进行一些按位算术并存储到整个字或四字.g ++ -O3生成了类似的代码.

题:

我想知道这段代码是否始终是线程安全的,如果没有,它将在什么条件下不会.也许我是非常偏执,但我觉得我需要一次操作四字,以确保安全.

#include <iostream>
#include <pthread.h>

class FermatLTParams
{
public:
    FermatLTParams(unsigned char *_dst, unsigned int _p, unsigned int _a, unsigned int _k)
        : dst(_dst), p(_p), a(_a), k(_k) {}

    unsigned char …
Run Code Online (Sandbox Code Playgroud)

c++ parallel-processing multithreading x86-64 image-processing

10
推荐指数
1
解决办法
169
查看次数

优化 64 位模数运算,以实现重复使用的运行时模数

我有数十亿个无符号 64 位数字 (x),我需要找到它们x % mm对所有人来说都是相同的,但不是编译时常量。 m大于一。

xm同样可能保存任何 64 位值。

(如果m是编译时常量,我可以相信编译器会尽力而为。)

由于m所有这些操作都是相同的,并且我有可用的存储空间,是否有一种优化可以让我x % mm每个操作都不同时更快地计算所有结果x

(我受到常量除法优化的启发,它将除法转换为乘法、移位和加法。C、Rust 或伪代码中的说明性代码会很棒。)

我看过该文档,但他们在不计算商的情况下计算模数的优化仅适用于 的除数2^n +/- 1

c optimization modulo rust

6
推荐指数
1
解决办法
193
查看次数