Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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语言中的内联向量运算_C - Fatal编程技术网

C语言中的内联向量运算

C语言中的内联向量运算,c,C,我用C做一些科学计算,需要移动很多向量 我定义了一些基本的乘法和加法函数 add(int size, double *out, double *x, double *y) 但是对于复杂的操作,代码很快就会变得很长,很难阅读 是否可以定义内联运算符(V1+V2)?或者有什么通用的最佳实践可以更容易地抽查代码中的数学错误?也许有些人会给恶作剧下定义 是否可以定义内联运算符(V1+V2) 但是它是在C++中。 起初我认为这是一个C++的问题,因为某种原因!p> 如果您可以使用C++,您可能可以使用S

我用C做一些科学计算,需要移动很多向量

我定义了一些基本的乘法和加法函数

add(int size, double *out, double *x, double *y)
但是对于复杂的操作,代码很快就会变得很长,很难阅读

是否可以定义内联运算符(V1+V2)?或者有什么通用的最佳实践可以更容易地抽查代码中的数学错误?也许有些人会给恶作剧下定义

是否可以定义内联运算符(V1+V2)

<0 >但是它是在C++中。

起初我认为这是一个C++的问题,因为某种原因!p>

如果您可以使用C++,您可能可以使用STL数组(其中的大小是模板参数,而不是存储值)。 它可能看起来像这样:

std::array<double, 7> a = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
std::array<double, 7> b = {0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
auto c = a + b;
auto d = a + b + c;
int A[4] = { 1, 2, 3, 4 };
int B[4] = { 4, 3, 2, 1 };
int C[4];
C[:] = A[:] + B[:];
B[:] = cosf(C[:]);
因此,在任何操作链中,您最多使用一个临时变量


std::array的内存布局应与本机数组相同,因此,如果您希望接触少量现有代码,则应能够非常轻松地(通过(ab)使用强制转换、typedef或预处理器)将此代码“注入”到现有程序中。

这称为“运算符重载”它的强< >强> > <强> > C++的一个特征。如果C++是你的选择,那么有很多关于如何重载运算符的教程。有些人认为它是邪恶的,因为:

  • 当代码脱离上下文时,很难判断实际会发生什么。例如,您可以在那里看到运算符,但如何知道它们是内置的还是重载的

  • 可以重载运算符并对其应用不常见的含义,例如(这是我在实际代码中看到的),可以重载“/”运算符(除法运算符)作为类的路径分隔符,该类以独立于操作系统的方式处理文件名:

    Filename f = Filename::MainFileSystem() / "folder1" / "folder2" / "file.txt";
    
    不要这样做。

  • 使用重载运算符也有好处:

  • 代码可以大大简化。您可以使用

    result = vec1 + vec2 + vec3;
    
    请注意,如上所述,仅通过查看该行代码很难判断是否将调用任何函数,但这一困难是否超过简化的好处是主观的

  • 您可以执行一些巧妙的技巧,例如,在不修改操作符的原始语义的情况下为您添加功能


  • 如果您不介意采用非标准解决方案,英特尔编译器支持C语言中的数组表示法扩展。以下是链接:

    基本上,您可以编写如下代码:

    std::array<double, 7> a = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
    std::array<double, 7> b = {0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
    auto c = a + b;
    auto d = a + b + c;
    
    int A[4] = { 1, 2, 3, 4 };
    int B[4] = { 4, 3, 2, 1 };
    int C[4];
    C[:] = A[:] + B[:];
    
    B[:] = cosf(C[:]);
    
    它还提供了许多数学函数的向量版本,因此您可以执行以下操作:

    std::array<double, 7> a = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
    std::array<double, 7> b = {0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
    auto c = a + b;
    auto d = a + b + c;
    
    int A[4] = { 1, 2, 3, 4 };
    int B[4] = { 4, 3, 2, 1 };
    int C[4];
    C[:] = A[:] + B[:];
    
    B[:] = cosf(C[:]);
    

    作为额外的奖励,如果你这样编写代码,它会被用SSE /AVX指令来矢量化。

    你是否考虑过使用C++?尝试:<代码>内联空添加(int大小,双*OUT,双*X,双*y)< />代码>还是我误解了问题?@ MyStudi:他想从<代码>添加(siZoof(FoO),OUT,FoO,bar);<代码>到代码> out = fo+bar > /COD>。这个问题被命名为C,而不是C++,这是一个很好的答案,我不认为需要删除,只是应该提到它是C++解决方案。这应该是答案。您知道这是否扩展到新的AVX512上吗?