小编Ste*_*ein的帖子

比较 Fortran 和 C++ 汇编程序的 int = floor(sqrt(...))

我在 Fortran 和 C++ 中分别实现了一个函数:

#include <math.h>

void dbl_sqrt_c(double *x, double *y){
   *y = sqrt(*x - 1.0);
   return;
}
Run Code Online (Sandbox Code Playgroud)
pure subroutine my_dbl_sqrt(x,y) bind(c, name="dbl_sqrt_fort")
   USE, INTRINSIC :: ISO_C_BINDING
   implicit none
   real(kind=c_double), intent(in)  :: x
   real(kind=c_double), intent(out) :: y

   y = sqrt(x - 1d0)
end subroutine my_dbl_sqrt
Run Code Online (Sandbox Code Playgroud)

我在编译器资源管理器中比较了它们:

Fortran:https : //godbolt.org/z/froz4rx97
C++:https : //godbolt.org/z/45aex99Yz

我阅读汇编程序的方式,它们基本上做相同的事情,但是 C++ 检查 sqrt 的参数是否为负,而 Fortran 则没有。我使用 googles 基准比较了它们的性能,但它们非常匹配:

--------------------------------------------------------
Benchmark              Time             CPU   Iterations
--------------------------------------------------------
bm_dbl_c/8          2.07 ns         2.07 ns    335965892
bm_dbl_fort/8       2.06 ns         2.06 …
Run Code Online (Sandbox Code Playgroud)

c++ performance assembly x86-64

40
推荐指数
2
解决办法
2462
查看次数

Rust无法找到箱子

我正在尝试在Rust中创建一个模块,然后从另一个文件中使用它.这是我的文件结构:

matthias@X1:~/projects/bitter-oyster$ tree
.
??? Cargo.lock
??? Cargo.toml
??? Readme.md
??? src
?   ??? liblib.rlib
?   ??? lib.rs
?   ??? main.rs
?   ??? main.rs~
?   ??? plot
?       ??? line.rs
?       ??? mod.rs
??? target
    ??? debug
        ??? bitter_oyster.d
        ??? build
        ??? deps
        ??? examples
        ??? libbitter_oyster.rlib
        ??? native

8 directories, 11 files
Run Code Online (Sandbox Code Playgroud)

这是Cargo.toml:

[package]
name = "bitter-oyster"
version = "0.1.0"
authors = ["matthias"]

[dependencies]
Run Code Online (Sandbox Code Playgroud)

这是主要的:

extern crate plot;

fn main() {
    println!("----");
    plot::line::test();
}
Run Code Online (Sandbox Code Playgroud)

这是lib.rs:

mod plot;
Run Code Online (Sandbox Code Playgroud)

这是情节/模型

mod …
Run Code Online (Sandbox Code Playgroud)

rust rust-crates

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

在Go中将固定大小的数组转换为可变大小的数组

我正在尝试将固定大小的数组转换[32]byte为可变大小的数组(切片)[]byte:

package main

import (
        "fmt"
)

func main() {
        var a [32]byte
        b := []byte(a)
        fmt.Println(" %x", b)
}
Run Code Online (Sandbox Code Playgroud)

但编译器抛出错误:

./test.go:9: cannot convert a (type [32]byte) to type []byte
Run Code Online (Sandbox Code Playgroud)

我该如何转换它?

arrays type-conversion go

16
推荐指数
2
解决办法
4235
查看次数

用平坦的记忆结构替换矢量矢量

我有以下类型:

std::vector<std::vector<int>> indicies
Run Code Online (Sandbox Code Playgroud)

其中内部向量的大小始终为2.问题是,向量在内存中是非连续的.我想用连续的东西替换内部向量,以便我可以抛出扁平数组:

int *array_a = (int *) &(a[0][0])
Run Code Online (Sandbox Code Playgroud)

如果新类型有[]运算符会很好,所以我不必更改整个代码.(如果有必要,我也可以自己实施).我的想法是:

std::vector<std::array<int, 2>>
Run Code Online (Sandbox Code Playgroud)

要么

std::vector<std::pair<int, int>>
Run Code Online (Sandbox Code Playgroud)

这些在内存中看起来如何?我写了一个小测试:

#include <iostream>
#include <array>
#include <vector>
int main(int argc, char *argv[])
{
    using namespace std;

    vector<array<int, 2>> a(100);

    cout << sizeof(array<int, 2>) << endl;

    for(auto i = 0; i < 10; i++){
        for(auto j = 0; j < 2; j++){
            cout << "a[" << i << "][" << j << "] " 
                <<&(a[i][j]) << endl;
        }
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这导致:

8
a[0][0] …
Run Code Online (Sandbox Code Playgroud)

c++ stl vector c++11

11
推荐指数
1
解决办法
882
查看次数

消息目录Matlab:未加载解释器

我在MATLAB中遇到了一个非常奇怪的错误,它似乎与我的程序没有直接关系.MATLAB甚至没有给我一个发生错误的行.

我的程序处理了很多文件.我可以处理它们的组而不会出现错误,但是当它们一起处理它们时我得到以下错误:

Caught "std::exception" Exception message is:
Message Catalog MATLAB:interpreter was not loaded from the file. Please check file location, format or contents
Run Code Online (Sandbox Code Playgroud)

这通常发生在大致相同的点上,但并不完全相同.我测试了这一点周围的所有文件,他们工作.这就是为什么我认为它与RAM有关.

如果我再次尝试运行程序,我会在开始时得到相同的错误,但重新启动MATLAB后,一切运行正常.

我想知道它是否是基于C++的错误,因为它包含'std :: ...'

你知道这个错误意味着什么以及如何修复它吗?

error-handling ram matlab

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

为什么比uint64快一倍?

我使用Matlab分析了以下程序profile.double和uint64都是64位变量.为什么比比较两个uint64要快两倍?这两个都不是比较的吗?

big = 1000000;

a = uint64(randi(100,big,1));
b = uint64(randi(100,big,1));
c = uint64(zeros(big,1));
tic;
for i=1:big
    if a(i) == b(i)
        c(i) = c(i) + 1;
    end
end
toc;

a = randi(100,big,1);
b = randi(100,big,1);
c = zeros(big,1);
tic;
for i=1:big
    if a(i) == b(i)
        c(i) = c(i) + 1;
    end
end
toc;
Run Code Online (Sandbox Code Playgroud)

这是配置文件的度量:

个人资料截图

这就是tictoc措施:

Elapsed time is 6.259040 seconds.
Elapsed time is 0.015387 seconds.
Run Code Online (Sandbox Code Playgroud)

当使用uint8..uint32或int8..int32而不是64位数据类型时,效果消失.

double performance matlab integer compare

7
推荐指数
1
解决办法
1581
查看次数

在图像中绘制标记

我正在使用Matplotlib画一幅画:

plt.imshow(bild)
plt.show()
Run Code Online (Sandbox Code Playgroud)

如何使用图像的坐标为此添加标记(例如,红点/箭头)?

python image matplotlib

7
推荐指数
3
解决办法
1万
查看次数

如何使用重复创建带有可选参数的Rust宏?

我目前正在研究Rust宏,我找不到任何有关重复的详细文档.我想用可选参数创建宏.这是我的想法:

macro_rules! single_opt {
    ($mand_1, $mand_2, $($opt:expr)* ) =>{
        match $opt {
            Some(x) => println!("1. {} 2. {}, 3. {}", $mand_1, $mand_2, x);
            None => single_opt!($mand_1, $mand_2, "Default");
        }
    }
}

fn main() {
    single_opt!(4,4);
}
Run Code Online (Sandbox Code Playgroud)

这个例子似乎已经过时了,因为我无法编译它.Rust书中非常简短地提到了这个主题.我如何让这个例子起作用?

macros pattern-matching rust

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

将 lcov 与 gcc-8 一起使用

我正在尝试确定我的测试覆盖率。为此,我使用较新版本的 gcc 编译我的程序:

\n\n
CC=/usr/local/gcc8/bin/gcc  FC=/usr/local/gcc8/bin/gfortran ./configure.sh  -external cmake -d\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用选项编译后,--coverage我运行测试并创建*.gcda,*.gcno*.o.provides.build文件。如果我运行类似的东西:

\n\n
> $ /usr/local/gcc8/bin/gcov slab_dim.f90.gcda                                                                             [\xc2\xb1develop \xe2\x97\x8f]\nFile \'/Local/tmp/fleur/cdn/slab_dim.f90\'\nLines executed:0.00% of 17\nCreating \'slab_dim.f90.gcov\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

这表明 gcov 运行良好。但是,如果我尝试对这些结果运行 lcov:

\n\n
lcov -t "result" -o ex_test.info -c -d CMakeFiles/\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于每个文件,我都会收到类似以下的错误消息:

\n\n
Processing fleur.dir/hybrid/gen_wavf.F90.gcda\n/Local/tmp/fleur/build.debug/CMakeFiles/fleur.dir/hybrid/gen_wavf.F90.gcno:version \'A82*\', prefer \'408R\'\n/Local/tmp/fleur/build.debug/CMakeFiles/fleur.dir/hybrid/gen_wavf.F90.gcno:no functions found\ngeninfo: WARNING: gcov did not create any files for /Local/tmp/fleur/build.debug/CMakeFiles/fleur.dir/hybrid/gen_wavf.F90.gcda!\n
Run Code Online (Sandbox Code Playgroud)\n\n

这与我使用系统标准时收到的错误消息相同/usr/bin/gcov

\n\n

这让我相信 lcov 调用旧的 gcov 而不是新的。如何强制 gcov 使用新版本?

\n

gcov lcov

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

为什么编译器不在我的范围表达式中使用 SIMD?

我有两种点积实现:一种是手工编码的https://godbolt.org/z/48EEnnY4r

int bla2(const std::vector<int>& a, const std::vector<int>& b){

    int res = 0;
    for(size_t i=0; i < a.size(); ++i){
        res += a[i]*b[i];
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)

一个使用 C++23 的std::views::zip https://godbolt.org/z/TsGW1WYnf

int bla(const std::vector<int>& a, const std::vector<int>& b){

    int res = 0;
    for(const auto& [x,y]  : std::views::zip(a,b)){
        res += x*y;
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)

在 godbolt 中,手工编码版本使用了大量 SIMD 指令,而基于 zip 的实现则没有。这里发生了什么?如果我使用迭代器实现它,它也会获得 SIMD。我认为在幕后范围只使用迭代器。这些表达式不等价吗?

c++ gcc simd auto-vectorization std-ranges

5
推荐指数
0
解决办法
162
查看次数