2022年8月13日 星期六

2022年8月10日 星期三

Using httpx in FastAPI to call Flask API

calculate.py

from flask import Flask, redirect, url_for, request
import datetime

app = Flask(__name__)

@app.route('/calculate',methods = ['POST', 'GET'])
def calculate():
   now = datetime.datetime.now()
   if request.method == 'POST':
      res = f"POST {now}"
   else:
      res = f"GET {now}"
   print(res)
   return res

if __name__ == '__main__':
   app.run(debug = True, host='0.0.0.0', port=5000)


client.py

import httpx

with httpx.Client() as client:
    r = client.post("http://127.0.0.1:5000/calculate")
    print(r.status_code)
    print(r.text)


api.py

# uvicorn main:app --reload
# pip install fastapi[all]
# pip install uvicorn

from fastapi import FastAPI
from enum import Enum
from typing import Union
import httpx

import webbrowser
webbrowser.open("http://127.0.0.1:8000")
webbrowser.open("http://127.0.0.1:8000/redoc")
webbrowser.open("http://127.0.0.1:8000/openapi.json")
webbrowser.open("http://127.0.0.1:8000/docs")

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}
    
@app.get("/pretend")
async def pretend():
    async with httpx.AsyncClient() as client:
        r = await client.post("http://127.0.0.1:5000/calculate")
        print(r.status_code)
        print(r.text)
        return r.text
   

2022年8月6日 星期六

Introduction to git and GitHub 2022

 Week 1


Reference

https://git-scm.com/docs/gittutorial

commit
mkdir project
git init
git add .
git commit
touch file1 file2 file3
git add file1 file2 file3
git diff --cached
git status
git commit
git commit -a
git log
git log -p
git log --stat --summary

branch
git branch experimental
git branch
git switch experimental
echo first >> file1
git commit -a
git switch master
echo second >> file1
git commit -a
git merge experimental
git diff
git commit -a
git branch -d experimental
git branch -D crazy-idea
TBC

Collaboration

git clone /home/alice/project myrepo\
cd myrepo
echo bob >> file.txt
git commit -a
alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master // pull = fetch + merge to current branch
alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD // range notation
alice$ gitk HEAD..FETCH_HEAD
alice$ git remote add bob /home/bob/myrepo
alice$ git fetch bob
alice$ git log -p master..bob/master  // better range notation
alice$ git merge bob/master
alice$ git pull . remotes/bob/master // what? pulling from her own remote-tracking branch?
bob$ git pull  // pull = fetch + merge to current branch
bob$ git config --get remote.origin.url
/home/alice/project
bob$ git config -l  // show git clone config
bob$ git branch -r origin/master
bob$ git clone alice.org:/home/alice/project myrepo

History

git log
git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
git show c82a22c39c
git show c82a22c39
git show c82a22c3
git show c82a22c
git show c82a22
git show HEAD # tip of current branch
git show experiment # tip of experiment branch
git show HEAD^ # parent of HEAD
git show HEAD^^ # grandparent of HEAD
git show HEAD~4 # great-great grandparent of HEAD
git show HEAD^1 # same as HEAD^
git show HEAD^2 # second parent of HEAD
git tag v2.5 1b2e1d63ff
git diff v2.5 HEAD
git branch stable v2.5  # create a new branch named stable based on v2.5
git reset --hard HEAD^  # reset to state at HEAD^ i.e. parent of HEAD
git grep "hello" v2.5
git log v2.5..v2.6 # commit between v2.5 and v2.6
git log v2.5.. # commit since v2.5
git log --since="2 week ago"  # commit from the last 2 weeks
git log v2.5.. Makefile # commit since v2.5 which modify Makefile
gitk --since="2 weeks ago" drivers/ # commits that modify directory
 

Diff

diff apple banana

diff -u apple banana

diff -u apple banana > diff.diff

meld, kdiff3, vimdiff

patch banana < diff.diff




2022年8月1日 星期一

KMV on Ubuntu 20.04 2022

 https://cloud.tencent.com/developer/article/1657533


check virtualization

sudo apt install cpu-checker
kvm-ok
echo should be 8

install

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager

sudo systemctl is-active libvirtd
echo should see active

group

sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
newgrp libvirt
newgrp kvm

bridge

ip addr | grep virb

4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000

manager

virt-manager

feeling

On N5105 8GB 256GB Ubuntu KVM Host, KVM Guest Windows 10 ISO + 2CPU + 4GB seems working well

display driver

https://blog.csdn.net/qq_38028248/article/details/115466576

https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.221-1/

public bridge

reference: https://levelup.gitconnected.com/how-to-setup-bridge-networking-with-kvm-on-ubuntu-20-04-9c560b3e3991

sudo nano /etc/sysctl.d/bridge.conf

net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0

sudo nano /etc/udev/rules.d/99-bridge.rules

ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", \           RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf" 

sudo nano /etc/netplan/00-installer-config.yaml

network:
  ethernets:
    wlp1s0:
      dhcp4: true
  version: 2

  bridges:
    br0:
      interfaces: [wlp1s0]
      dhcp4: yes

sudo netplan apply

echo "now can google"

ip addr

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 00:e0:4c:36:bf:8c brd ff:ff:ff:ff:ff:ff
3: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 38:87:d5:b7:81:c1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.51/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp1s0
       valid_lft 86368sec preferred_lft 86368sec
    inet6 fe80::9b00:9da:fccf:ca57/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
5: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 26:9c:28:b8:4a:d2 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::249c:28ff:feb8:4ad2/64 scope link
       valid_lft forever preferred_lft forever


Reference 1

如何在 Ubuntu 20.04 上安装 KVM

KVM(基于内核的虚拟机)是一个内置于Linux内核的开源虚拟化技术。它允许你基于 Linux 或者 Windows 运行多个隔离的客户机虚拟机器。每一个客户机都拥有自己的操作系统和专用的虚拟硬件,例如 CPU(s), 内存, 网络接口和存储。

这篇指南提供了关于如何在 Ubuntu 20.04 上安装和配置 KVM 的指令。我们也会向你展示如何创建虚拟机,它们将被用作不同应用的开发环境。

一、前提条件

想要运行超过 2GB 内存的客户机,你必须拥有一个 64位主机系统。

在继续安装之前,确保你的 Ubuntu 主机支持 KVM 虚拟化。这个系统必须拥有 支持 VT-x(vmx)的 Intel 处理器 或者支持 AMD-V (svm) 技术的 AMD 处理器。

输入下面的grep命令来看看你的吹气是否支持硬件虚拟化:

grep -Eoc '(vmx|svm)' /proc/cpuinfo

如果你的 CPU 支持硬件虚拟化,这个命令将会打印出大于0的数字,这代表 CPU 核心数目。否则,如果输出为0,它意味着这个 CPU 不支持硬件虚拟化。

在一些机器上,虚拟化技术可能被厂商在 BIOS 中禁用了。

想要检查 VT 是否在 BIOS 中启用了,使用kvm-ok工具,它被包含在cpu-checker软件包。以 root 或者其他有 sudo 权限用户身份运行下面的命令,安装这个软件包:

sudo apt update
sudo apt install cpu-checker

一旦安装完成,检查你的系统是否可以运行硬件加速的 KVM 虚拟机:

kvm-ok

如果处理器虚拟化能力没有在 BIOS 中被禁用,命令将会打印出:

INFO: /dev/kvm exists
KVM acceleration can be used

否则,这个命令将会打印一个失败信息,和一个关于如何启用这个组件的简短消息。启用 AMD-V 或者 VT 技术的过程依赖于你的主板和处理器类型。根据你的主板文档信息来配置你的系统 BIOS。

二、在 Ubuntu 20.04 上安装 KVM

运行下面的命令安装 KVM,和额外的虚拟化管理软件包:

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager
  • qemu-kvm - 为 KVM 管理程序提供硬件模拟的软件程序
  • libvirt-daemon-system - 将 libvirt 守护程序作为系统服务运行的配置文件
  • libvirt-clients - 用来管理虚拟化平台的软件
  • bridge-utils - 用来配置网络桥接的命令行工具
  • virtinst - 用来创建虚拟机的命令行工具
  • virt-manager - 提供一个易用的图形界面,并且通过libvirt 支持用于管理虚拟机的命令行工具

一旦软件包被安装好,libvirt 守护程序将会自动启动。你可以通过运行下面的命令,验证它:

sudo systemctl is-active libvirtd

输出:

active

想要创建和管理虚拟机,你需要添加你的用户到“libvirt” 和 “kvm” 用户组。输入:

sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

$USER是一个环境变量,用来记住当前登录用户的名字。

登出,并且重新登录,以便用户组被刷新。

三、网络设置

在libvirt 安装过程中,一个被称为 “virbr0”的桥接设备默认被创建。这个设备使用 NAT 来连接客户机到外面的世界。

运行 brctl 工具来列出当前的桥接和它们连接的接口:

brctl show

输出:

bridge name	bridge id		      STP enabled	interfaces
virbr0		  8000.52540089db3f	yes		      virbr0-nic

“virbr0” 桥接没有添加任何的物理接口。“virbr0-nic”是一个虚拟设备,没有任何流量通过。这个设备唯一的目的就是避免修改“virbr0” 桥接的 MAC 地址。

网络设置适合大部分 Ubuntu 桌面用户,但是有限制。如果你想从外面的本地网络访问客户机,你需要创建一个新的桥接,并且配置它,以便客户机可以通过主机的物理接口连接到外部世界。

四、创建虚拟机

现在 KVM 在你的 Ubuntu 桌面被安装,让我们一起去创建第一个虚拟机。我们可以从命令行或者使用virt-manager应用。

下载你想要安装的操作系统的 ISO 镜像并且按照下面的步骤来创建你的虚拟机:

01.在搜索栏输入“Virtual Machine Manager”并且点击图标来启动应用。

02.在应用启动后,从顶部菜单点击“File” -> “New Virtual Machine”:

03.一个新窗口将会显示。选择 “Local install media” 并且点击 “Forward” 按钮。

04.提供你的 ISO 镜像路径,并且点击 Forward 按钮。

05.在下一个屏幕,选择虚拟机 VM 的内存和 CPU 设置。点 Forward。

06.下一步,选择“Create a disk image for the virtual machine” 并且选择虚拟机的磁盘空间大小。点击 Forward。

07.输入你的虚拟机名字并且点击 “Finish”。

08.虚拟机启动,并且一个新窗口将会打开:

从这里,你就可以按照屏幕的操作,去完成操作系统的安装。

一旦操作系统被安装好,你可以从virt-manager去访问它,使用 ssh 或者使用 Serial Console 接口。

五、总结

我们为你展示如何在 Ubuntu 20.04 系统上安装 KVM。现在你可以创建 Windows 或者 Linux 客户机。想要查找更多关于 KVM 的信息,浏览:KVM 文档页面

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://www.itcoder.tech/复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。


Reference 2

KVM中给windows虚拟机安装virtio驱动
R.scorpio
于 2021-04-06 17:53:03 发布 792
收藏 2
分类专栏: KVM 文章标签: 虚拟机
版权
KVM 专栏收录该内容
4 篇文章 0 订阅
订阅专栏

KVM下windows虚拟机默认disk使用的是Qemu IDE硬盘,网卡默认是e1000网卡。为了使kvm主机在相同的配置下,有更好的效率,需要命名用半虚拟化将驱动改为为了virtio ,使硬盘工作在SCSI模式,网卡为Virtio类型。

如果需要给windows安装virtio驱动,可以按如下方法操作:
1、在需要安装驱动的虚机上挂载对应驱动版本的ISO镜像。

2、进入虚机后查看cdrom。
在这里插入图片描述
3、进入设备管理器查看其他设备,带有叹号的SCSI控制器。
在这里插入图片描述
4、右击该设备,选择更新驱动程序,然后选择“浏览计算机以查找驱动程序软件”,在搜索位置上选择加载的CDROM(可以发现,在该iso镜像中包含了很多种I/O设备的virtio驱动,并且每种virtio驱动的目录下都对应有不同的OS类型),这里不需要自己手动选择这些,只需要选择“CD驱动器”即可,让系统自动搜索合适的驱动程序。
virtio驱动5、然后下一步,自动搜索到了Virtio SCSI controller的驱动程序了,选择安装。
在这里插入图片描述
6、至此驱动程序安装完毕。
在这里插入图片描述
————————————————
版权声明:本文为CSDN博主「R.scorpio」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38028248/article/details/115466576


Reference 3 not exist

End

2022年7月21日 星期四

What does the "lock" instruction mean in x86 assembly?

 


Code

#include <atomic>
#include <cassert>
#include <iostream>
#include <thread>
#include <vector>

std::atomic_ulong my_atomic_ulong(0);
unsigned long my_non_atomic_ulong = 0;
unsigned long my_arch_atomic_ulong = 0;
unsigned long my_arch_non_atomic_ulong = 0;
size_t niters;

void threadMain() {
for (size_t i = 0; i < niters; ++i) {
my_atomic_ulong++;
my_non_atomic_ulong++;
__asm__ __volatile__ (
"incq %0;"
: "+m" (my_arch_non_atomic_ulong)
:
:
);
__asm__ __volatile__ (
"lock;"
"incq %0;"
: "+m" (my_arch_atomic_ulong)
:
:
);
}
}

int main(int argc, char **argv) {
size_t nthreads;
if (argc > 1) {
nthreads = std::stoull(argv[1], NULL, 0);
} else {
nthreads = 2;
}
if (argc > 2) {
niters = std::stoull(argv[2], NULL, 0);
} else {
niters = 10000;
}
std::vector<std::thread> threads(nthreads);
for (size_t i = 0; i < nthreads; ++i)
threads[i] = std::thread(threadMain);
for (size_t i = 0; i < nthreads; ++i)
threads[i].join();
assert(my_atomic_ulong.load() == nthreads * niters);
assert(my_atomic_ulong == my_atomic_ulong.load());
std::cout << "my_atomic_ulong " << my_atomic_ulong << std::endl;
std::cout << "my_non_atomic_ulong " << my_non_atomic_ulong << std::endl;
assert(my_arch_atomic_ulong == nthreads * niters);
std::cout << "my_arch_atomic_ulong " << my_arch_atomic_ulong << std::endl;
std::cout << "my_arch_non_atomic_ulong " << my_arch_non_atomic_ulong << std::endl;
}


Results

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp -pthread
./main.out 2 10000
ricky@ricky-gn41:~/play/playatomicadd$ ./main.out 2 10000
my_atomic_ulong 20000
my_non_atomic_ulong 19494
my_arch_atomic_ulong 20000
my_arch_non_atomic_ulong 19405
ricky@ricky-gn41:~/play/playatomicadd$ ./main.out 2 10000
my_atomic_ulong 20000
my_non_atomic_ulong 17804
my_arch_atomic_ulong 20000
my_arch_non_atomic_ulong 17977




End





2022年7月20日 星期三

MESI Protocol Cache Invalidate 2022

首页 / MESI缓存一致性协议详解 

存储器分成几个级别

Register, L1 Cache, L2 Cache, L3 Cache, Memory, SSD or HDD

L1P for program (sometimes L1I for L1 instruction)
L1D for data
L2 Cache is per CPU core (private)
L3 Cache is shared among core (public)

Bus

Memory 16GB

J4105

https://www.cpu-world.com/CPUs/Celeron/Intel-Celeron%20J4105.html

L1$ 256 KiB
L1I$ 128 KiB 4x32 KiB 8-way set associative
L1D$ 96 KiB 4x24 KiB 6-way set associative write-back
L2$ 4 MiB 1x4 MiB 16-way set associative write-back

Problem

If both core execute x=x+1, its private L1D data is not visible to other. Parallel computing causes x==1 not x==2.

Solution 1

给bus总线加锁,谁访问内存的数据,就给bus加上lock,这个时候不处理完谁也不能加载和改变内存的数据,也就会导致cpu间的阻塞。这个问题可以解决但是性能太低了。

Solution 2

MESI 缓存一致性协议了。他是对单个缓存行来进行加锁,不会影响内存中其他的数据的读写操作。

MESI

分别是M(modified)、E(exclusive)、S(shared)、I(invalid)。

M(修改):该Cache line有效,数据被修改了和内存中的数据不一致,但是仅存在本cache中。
E(独享):该Cache line有效,数据和内存一致,仅存在本cache中。
S(共享):该Cache line有效,数据存在多个缓存中。
I(无效):该Cache line无效。

四个状态,所以每个缓存行都有2个bit来进行表示当前Cache line的状态。

CPU缓存行


最常见的缓存行大小是64个字节。当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。

缓存是由缓存行组成的,通常是64字节,可以存8个long类型的变量。

Why Array? 得到免费缓存加载所带来的优势

请记住我们必须以整个缓存行作为单位来处理(译注:这是CPU的实现所规定的






as
dasdasdasd

Read


1. https://www.jianshu.com/ CPU缓存行 胖虎大哥
2. https://blog.csdn.net/qq_27680317/article/details/78486220
3. 一篇对伪共享、缓存行填充和CPU缓存讲的很透彻的文章 https://blog.csdn.net/qq_27680317/article/details/78486220
4. MESI 缓存一致性协议引发的一些思考 https://segmentfault.com/a/1190000040984124
5. Visualize MESI protocol https://www.scss.tcd.ie/Jeremy.Jones/vivio/caches/MESIHelp.htm
6. https://www.ics.uci.edu/~aburtsev/cs5460/lectures/lecture13-memory-ordering/lecture13-memory-barriers.pdf

TBC since 2022-07-20

1. LINUX KERNEL MEMORY BARRIERS Hard, not yet read all. https://www.kernel.org/doc/Documentation/memory-barriers.txt













More

End

2022年7月2日 星期六

C++11 Review on 2022 + C++14

 C++ Weekly EP 176 C++11 in 12 Minutes by Jason Turner 85.6K

1. auto

2. range based for loop

3. lambda [](int i){return i<3;}

4. variadic templates

template<class Pack>
Pack call(const Pack& v) {
return v;
}

template<class Pack, class... Packs>
Pack call(const Pack& pack, const Packs&... packs) {
std::cout << __PRETTY_FUNCTION__ << "\n";
return pack + call(packs...);
}

5. unique_ptr

6. constexpr int get_value() {return 5*3; }

That's all 6 of them.

But not mentioned

std::move
T&&
thread, mutex, condition_variable, packaged_task, std::future
std::tuple, chrono, decltype, override, nullptr, enum class, unordered_map, std::ref

C++ Weekly EP 178 C++14 in 9 Minutes by Jason Turner 85.6K

Like a bugfix to C++11

1. auto return type for template

template<typename T>
auto function(const T& vec, int value) {
const auto count = std::count(begin(vec), end(vec), value);
return count
}

2. lambda generic

const auto count = std::count(begin(vec), end(vec), [](const auto i){return i<3;});

3. lambda generailized capture

[value = [](){return 3;}](const auto i){return i<value;};

4. make_unique

auto pointer(std::make_unique<int>(5));

5. constexpr with loops, switch, multiple returns

constexpr int get_value() {
int x = 5;
int y = 3;
return x*y;  // C++14 more statements ok, C++11 only 1 statement
}

C++ Weekly EP 190 C++17 in 10 Minutes by Jason Turner 85.6K

1. Guaranteed copy or move elision

#include <memory>
auto factory() {return std::make_unqiue<int>();}
int main() {auto object=factory();}  // must have no copy here

2. non const constexpr reference

reference operator[](size_type pos);
constexpr reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
constexpr const_reference operator[](size_type pos) const;

3. constexpr lambdas

constexpr auto l = [](){};

4. std::string_view

constexpr std::string_view name = "hello";




a

sfd

sadf

safs

df

sadf

sadf

sad

asdads















End

2007 to 2023 HP and Dell Servers Comparison

  HP Gen5 to Gen11  using ChatGPT HP ProLiant Gen Active Years CPU Socket Popular HP CPUs Cores Base Clock Max RAM Capacity Comparable Dell ...