< 返回我的博客

qwy16 发表于 2020-04-21 01:28

Tags:rust, Wired Logic, Multiversion, Spark, Android

1 - Wired Logic - 运行在浏览器上的基于像素的电子元件模拟器(用Rust语言编译成WASM)

Wired Logic - a pixel-based digital circuit simulator running in a browser (Rust compiled into WASM).

wired-logic启发,wired-logic-rs 是一个基于像素的数字电路模拟器,核心技术采用RustWebAssembly

wired-logic-rs 是怎么工作的呢? 系统先对图像进行扫描,然后采集一个线路,电能源,和各种晶体管,收集成一个集合, 然后对这些集合元素运行模拟仿真程序,只要确保模拟的状态不会重复就算是模拟成功。 然后再把模拟仿真结果渲染在一个GIF格式的图像上。

手动编译步骤:

$ wasm-pack build
$ npm install

$ npm run serve     # to start the webpack dev server
$ npm run bundle    # to create the production bundle

点击进入模拟例子-Goto the Online Simulator

更多请阅读-Read More in Project Github

2 - Multiversion 0.5.0, 多版本函数宏,现在已经"可以跑生产系统"了。

Multiversion 0.5.0, now "production ready"

Multiversion - 是Rust语言支持多版本函数的属性宏.

什么是function multiversioning?

大部分的CPU架构都有自己独特的指令集支持一些额外的功能。最常见的例子包括x86/x86-64 上的SSE & AVXNEON上的ARM/AArch64指令集扩展Single Instruction, Multiple Data(SIMD)。 这些指令集扩展可以给某些特殊的函数提升大量的运行速度。这些特殊的功能是不能胡乱的编译到一个 不支持这些特殊功能CPU的可执行文件里去的,那样往往会造成系统崩溃。

Function multiversioning是一种特殊的编译方法,通过编译包含特殊功能支持的不同版本的函数 能够在运行时runtime检测到这些特殊的功能并匹配不同的版本的可执行函数。

Function multiversioning功能:

  • 动态调控,启用运行时CPU功能检测
  • 静态调控,避免嵌套式的重复功能检测(但允许行内嵌套)
  • 支持所有类型的函数,包括generic和async类型的函数

例子: 用clone属性宏来实现多版本函数,类似GCC的target_clones

use multiversion::multiversion;

#[multiversion]
#[clone(target = "[x86|x86_64]+avx")]
#[clone(target = "x86+sse")]
fn square(x: &mut [f32]) {
   for v in x {
       *v *= *v;
   }
}

multiversiontarget属性宏来实现多版本函数.

use multiversion::{multiversion, target};

#[target("[x86|x86_64]+avx")]
unsafe fn square_avx(x: &mut [f32]) {
   for v in x {
       *v *= *v;
   }
}

#[target("x86+sse")]
unsafe fn square_sse(x: &mut [f32]) {
   for v in x {
       *v *= *v;
   }
}

#[multiversion]
#[specialize(target = "[x86|x86_64]+avx", fn = "square_avx", unsafe = true)]
#[specialize(target = "x86+sse", fn = "square_sse", unsafe = true)]
fn square(x: &mut [f32]) {
   for v in x {
       *v *= *v;
   }
}

更多信息请点击crates官网说明-Read More

3 - 软件开发者经济学:现在估计全球有60万活跃Rust程序员。

下面链接是长达40多页纸的调查报告(可能国内用户需要科学上网才能下载)

  • DEVELOPER ECONOMICS: STATE OF THE DEVELOPERNATION 18th EDITION, PUBLISHED APRIL 2020
  • 根据2019年第四季度对超过17000名软件开发人员进行的抽样调查的趋势报告

Active Rust developers estimated at 0.6 million (pdf, page 10)

4 - 如何在Windows 10系统环境安装原生Rust编程环境

How to install rust on Windows 10 (native)

下面是快速安装Windows 10 2004的步骤:

  1. 下载并运行rustup.rs
  2. 下载Build Tools for Visual Studio 2019,一般这个下载隐藏在微软下载链接的"Tools for Visual Studio 2019"下面。
  3. 运行Build Tools for Visual Studio 2019 Installer并选择:
    • C++ Tools
  4. C++ Tools中还必须同时选择安装"Windows 10 SDK",安装程序提供多个版本,选最新的版本安装就好。

测试看看是否安装成功:

  1. 打开PowerShell或命令行窗口,输入下面的命令并保证没有错误。
  2. 切换到临时文件夹:cd %TEMP%
  3. 创建一个测试项目:cargo new toolchain_test
  4. 进入项目所在目录:cd toolchain_test
  5. 编译并运行"Hello, world!"程序:cargo run

然后你应该可以得到一个编译的过程并看到结果显示"Hello, world!"

如果遇到类似cargo command not found的错误,你需要检查一下你的%PATH%看看是否设置好。

5 - Apache SparkRust语言绑定

Rust bindings for Apache Spark

这里例子演示使用Ballista Rust DataFrame API运行一个Apache Spark的查询请求.

Rust Client:

例子程序使用Ballista's的[Rust DataFrame](https://github.com/ballista-compute/ballista/blob/master/rust/src/dataframe.rs). 创建一个逻辑查询计划,对一个CVS文件做聚合查询:

let spark_master = "local[*]";

let mut spark_settings = HashMap::new();
spark_settings.insert("spark.app.name", "rust-client-demo");
spark_settings.insert("spark.ballista.host", "localhost");
spark_settings.insert("spark.ballista.port", "50051");

let ctx = Context::spark(spark_master, spark_settings);

let path = "/mnt/nyctaxi/csv/yellow/2019/yellow_tripdata_2019-01.csv";

let df = ctx
.read_csv(path, Some(nyctaxi_schema()), None, true)?
.aggregate(
   vec![col("passenger_count")], // group by 
   vec![min(col("fare_amount")), max(col("fare_amount"))] // aggregates
)?;

// print the query plan
df.explain();

// collect the results from the Spark executor
let results = df.collect().await?;

// display the results
utils::print_batches(&results)?;

当代码执行的时候collect()函数会将逻辑计划编码成protobuf格式, 然后发送给在spark_settings设置中设置了服务端口并运行了Ballista Spark Executor执行器的远程服务器节点。

上面的例子程序将执行显示如下结果:

Aggregate: groupBy=[[#passenger_count]], aggr=[[MIN(#fare_amount), MAX(#fare_amount)]]
 TableScan: /mnt/nyctaxi/csv/yellow/2019/yellow_tripdata_2019-01.csv projection=None
+-----------------+-------+-----------+
| passenger_count | MIN   | MAX       |
+-----------------+-------+-----------+
| 1               | -362  | 623259.86 |
| 6               | -52   | 262.5     |
| 3               | -100  | 350       |
| 5               | -52   | 760       |
| 9               | 9     | 92        |
| 4               | -52   | 500       |
| 8               | 7     | 87        |
| 7               | -75   | 78        |
| 2               | -320  | 492.5     |
| 0               | -52.5 | 36090.3   |
+-----------------+-------+-----------+

Spark Executor Ballista的Spark执行器Spark Executor 在收到客户端发送过来的使用protobuf格式编码的逻辑查询计划请求后翻译 成如下的Spark执行计划:

== Physical Plan ==
*(2) HashAggregate(keys=[passenger_count#3], functions=[min(fare_amount#10), max(fare_amount#10)])
+- Exchange hashpartitioning(passenger_count#3, 200), true, [id=#18]
   +- *(1) HashAggregate(keys=[passenger_count#3], functions=[partial_min(fare_amount#10), partial_max(fare_amount#10)])
      +- *(1) Project [passenger_count#3, fare_amount#10]
         +- BatchScan[passenger_count#3, fare_amount#10] CSVScan Location: InMemoryFileIndex[file:/mnt/nyctaxi/csv/yellow/2019/yellow_tripdata_2019-01.csv], ReadSchema: struct<passenger_count:int,fare_amount:double>

上面的例子是用到了Apache Arrow Flight协议, 想了解更多请参阅SparkFlightProducer代码实现。

6 - Rust语言Android SDK升级到API level 16了!(直接从level 14升级)

Upgrade Rust's Android SDK to API level 16 #71123

From 日报小组 BobQ(qwy16)

独立日报订阅地址:

社区学习交流平台订阅:

评论区

写评论

还没有评论

1 共 0 条评论, 1 页