Skip to content

Commit

Permalink
feat: add open lesson
Browse files Browse the repository at this point in the history
refactor: delete tanker

style: gw name

feat: add base and third-party examples

feat: add vector addition

feat: add simd example

refactor: boost perfomance via type narrow down

fix: delete reduntant movs

feat: add simd slice contains

style: add comments

refactor: add slice header

fix: header

refactor: add comments

fix: comment

feat: add some new asm code

feat: add lection_1 examples

feat: add lection 3 examples

feat: add lection_7 examples

refactor: delete generated data
  • Loading branch information
IgorWalther committed Sep 13, 2024
1 parent 054c2c1 commit 9f4fa21
Show file tree
Hide file tree
Showing 78 changed files with 102,453 additions and 279 deletions.
16 changes: 7 additions & 9 deletions .github/workflows/gormi.yaml → .github/workflows/generic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,27 @@ name: Test CI for Go optimizations course

on: [ push ]


# TDOO: classroom

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
os: [ macos-latest ]

steps:
- uses: actions/checkout@v4
- name: setup go
uses: actions/setup-go@v5
with:
go-version: '1.22.2'
cache-dependency-path: homeworks/hw1/go.sum
cache-dependency-path: open_lessons/asm/go.sum
- name: dependencies
working-directory: ./homeworks/hw1
working-directory: ./open_lessons/asm
run: go mod tidy
- name: test
working-directory: ./homeworks/hw1
working-directory: ./open_lessons/asm
run: go test -v ./...
# - name: test artifacts
# uses: actions/upload-artifact@v4
# with:
# name: results
# path: ./homeworks/hw2 // TODO
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
*.prof
*bin
*bin
*.DS_STORE
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func main() {
}

if testEnv != "TEST_ENV_DATA" {
panic("test inh mismatch")
panic("vector_addition inh mismatch")
}

reader := bufio.NewReader(os.Stdin)
Expand Down
1 change: 1 addition & 0 deletions homeworks/hw2/lower_bound_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ loop:

CMPQ R11, CX

// TODO: open_lesson
CMOVQLE R10, R8
CMOVQGT R10, R9

Expand Down
3 changes: 3 additions & 0 deletions homeworks/hw2/lower_bound_arm64.s
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ loop:
MOVD (R12), R5
CMP R2, R5

// assembly
// CMP R1, R3 // Сравнивает значения в регистрах R1 и R3.
// CSEL R6, R1, R3, LT // R6 = если R1 < R3, то R1, иначе R3
CSEL LE, R13, R3, R3
CSEL GT, R13, R1, R1

Expand Down
6 changes: 4 additions & 2 deletions homeworks/hw2/slice_sum_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
#define ZERO(r) \
XORQ r, r

// TODO: comments

// func SumSlice(s []int32) int64
TEXT ·SumSlice(SB), NOSPLIT, $0
MOVQ x_base+0(FP), AX // ptr
Expand All @@ -15,6 +13,10 @@ loop:
CMPQ DX, $0
JE done
XORQ CX, CX

// Move Long to Quad with Sign extend
// Правильно расширяем 32-битное до 64-битного
// в случае отрицательных значений
MOVLQSX (AX), R9
ADDQ R9, R10

Expand Down
2 changes: 0 additions & 2 deletions homeworks/hw2/word_count_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
#define ZERO(r) \
MOVQ $0, R2

// TODO: comments

// func WordCount(data []rune) int32
TEXT ·WordCount(SB), $32-24
MOVQ data_base+0(FP), AX
Expand Down
17 changes: 9 additions & 8 deletions homeworks/hw2/word_count_arm64.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@
#define ZERO(r) \
MOVD $0, R2

// TODO: comments


// func WordCount(data []rune) int32
// R5 - cur symbol
// R6 - word flag
// R7 - result
// Здесь 32 - размер стек фрейма, 24 - размер аргументов
TEXT ·WordCount(SB), $32-24
LDP data_base+0(FP), (R0, R1) // R0 - data_ptr, R1 - len
LDP data_base+0(FP), (R0, R1)
MOVW $0, R6
MOVW $0, R7

Expand All @@ -22,26 +16,33 @@ loop:
ADD $4, R0
SUB $1, R1

// Перед вызовом другой функции кладём данные и аргументы на стек
MOVD R0, f-0(SP)
MOVD R1, f-8(SP)
MOVW R6, f-16(SP)
MOVW R7, f-20(SP)

MOVW R5, r-32(SP)

// Обертка над unicode.IsSpace
CALL ·isSpace(SB)
MOVW s-24(SP), R8

// Достаем результат и данные обратно
MOVD f-0(SP), R0
MOVD f-8(SP), R1
MOVW f-16(SP), R6
MOVW f-20(SP), R7

// Test Bit and Branch if Zero
TBZ $0, R8, character
MOVW $0, R6

B loop

character:
// R6 - word flag
// Инвертируем все биты и делаем AND с 1
MVN R6, R6
AND $1, R6
ADD R6, R7
Expand Down
1 change: 1 addition & 0 deletions landing_examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.test
3 changes: 3 additions & 0 deletions landing_examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.PHONY: prof
prof:
go test -bench=. -benchmem -cpuprofile=cpu.prof -memprofile=mem.prof
66 changes: 66 additions & 0 deletions lections/lection_1/cache_contention/cache_contention_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cache_contention

import (
"golang.org/x/sys/cpu"
"math/rand/v2"
"runtime"
"sync"
"sync/atomic"
"testing"
"unsafe"
)

const cacheLineSize = unsafe.Sizeof(cpu.CacheLinePad{})

func BenchmarkCacheContentionWithoutPadding(b *testing.B) {
type WorkerStatistics struct {
Value atomic.Int64
_ [cacheLineSize - 8]byte
}

workers := runtime.NumCPU()
statistics := make([]WorkerStatistics, workers)

wg := new(sync.WaitGroup)

for workerID := 0; workerID < workers; workerID++ {
wg.Add(1)
go func() {
defer wg.Done()

for j := 0; j < b.N; j++ {
statistics[workerID].Value.Add(externalStatisticSourceByID(int64(workerID)))
}
}()
}

wg.Wait()
}

func BenchmarkCacheContentionWithPadding(b *testing.B) {
type WorkerStatistics struct {
Value atomic.Int64
}

workers := runtime.NumCPU()
statistics := make([]WorkerStatistics, workers)
wg := new(sync.WaitGroup)

for workerID := 0; workerID < workers; workerID++ {
wg.Add(1)

go func() {
defer wg.Done()

for j := 0; j < b.N; j++ {
statistics[workerID].Value.Add(externalStatisticSourceByID(int64(workerID)))
}
}()
}

wg.Wait()
}

func externalStatisticSourceByID(id int64) int64 {
return rand.N[int64](42*id%10 + 1)
}
5 changes: 5 additions & 0 deletions lections/lection_1/cache_lines/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module lection_1

go 1.22.1

require golang.org/x/sys v0.24.0
2 changes: 2 additions & 0 deletions lections/lection_1/cache_lines/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
15 changes: 15 additions & 0 deletions lections/lection_1/cache_lines/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"
"golang.org/x/sys/cpu"
"unsafe"
)

const cacheLineSize = unsafe.Sizeof(cpu.CacheLinePad{})

func main() {
a := 42
fmt.Println(fmt.Sprintf("%064b", &a))
fmt.Println(cacheLineSize)
}
5 changes: 5 additions & 0 deletions lections/lection_1/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module lection_1

go 1.22.1

require golang.org/x/sys v0.24.0
2 changes: 2 additions & 0 deletions lections/lection_1/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
1 change: 1 addition & 0 deletions lections/lection_1/verlog_mips_cpu/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.out
9 changes: 9 additions & 0 deletions lections/lection_1/verlog_mips_cpu/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.PHONY: test
test:
iverilog -g2001 cpu_test.v
./a.out


.PHONY: view
view:
gtkwave dump.vcd
32 changes: 32 additions & 0 deletions lections/lection_1/verlog_mips_cpu/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Структура процессора
1) Память команд и данных, модуль [memory.v](./cpu-template/memory.v)
2) Регистровый файл, модуль [register_file.v](./cpu-template/register_file.v)
3) Модуль для одиночного 32-битного регистра PC в [d_flop.v](./cpu-template/d_flop.v)
4) Модуль [util.v](./cpu-template/util.v) содержит вспомогательные модули, которые могут быть полезны
при реализации процессора.


| Команда | opcode | rs | rt | imm |
|---------|--------|-------|-------|------------------|
| lw | 100011 | xxxxx | xxxxx | xxxxxxxxxxxxxxxx |
| sw | 101011 | xxxxx | xxxxx | xxxxxxxxxxxxxxxx |
| beq | 000100 | xxxxx | xxxxx | xxxxxxxxxxxxxxxx |

| Команда | opcode | rs | rt | rd | shamt | funct |
|---------|--------|-------|-------|-------|-------|--------|
| add | 000000 | xxxxx | xxxxx | xxxxx | 00000 | 100000 |
| sub | 000000 | xxxxx | xxxxx | xxxxx | 00000 | 100010 |
| and | 000000 | xxxxx | xxxxx | xxxxx | 00000 | 100100 |
| or | 000000 | xxxxx | xxxxx | xxxxx | 00000 | 100101 |
| slt | 000000 | xxxxx | xxxxx | xxxxx | 00000 | 101010 |

| Команда | opcode | rs | rt | imm |
|---------|--------|-------|-------|------------------|
| addi* | 001000 | xxxxx | xxxxx | xxxxxxxxxxxxxxxx |
| andi* | 001100 | xxxxx | xxxxx | xxxxxxxxxxxxxxxx |
| bne | 000101 | xxxxx | xxxxx | xxxxxxxxxxxxxxxx |

| Команда | opcode | addr |
|---------|--------|----------------------------|
| j | 000010 | xxxxxxxxxxxxxxxxxxxxxxxxxx |
| jal | 000011 | xxxxxxxxxxxxxxxxxxxxxxxxxx |
76 changes: 76 additions & 0 deletions lections/lection_1/verlog_mips_cpu/cpu_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
`include "mips_cpu.v"
`include "memory.v"
`include "register_file.v"
`include "d_flop.v"

module cpu_test();
reg clk;

initial begin
$dumpfile("./dump.vcd");
$dumpvars;
end

// Инициализируем процессор
wire[31:0] instruction_memory_a, instruction_memory_rd;

instruction_memory cpu_instruction_memory(.a(instruction_memory_a), .rd(instruction_memory_rd));

wire data_memory_we;
wire[31:0] data_memory_a, data_memory_rd, data_memory_wd;
wire[31:0] pc, pc_new;

d_flop program_counter(.d(pc_new), .clk(clk), .q(pc));

data_memory cpu_data_memory(.a(data_memory_a), .we(data_memory_we), .clk(clk), .wd(data_memory_wd), .rd(data_memory_rd));

wire register_we3;
wire[4:0] register_a1, register_a2, register_a3;
wire[31:0] register_rd1, register_rd2, register_wd3;

register_file cpu_register(.clk(clk),
.we3(register_we3),
.a1(register_a1),
.a2(register_a2),
.a3(register_a3),
.wd3(register_wd3),
.rd1(register_rd1),
.rd2(register_rd2));

mips_cpu cpu(.clk(clk),
.pc(pc),
.pc_new(pc_new),
.instruction_memory_a(instruction_memory_a),
.instruction_memory_rd(instruction_memory_rd),
.data_memory_a(data_memory_a),
.data_memory_rd(data_memory_rd),
.data_memory_we(data_memory_we),
.data_memory_wd(data_memory_wd),
.register_a1(register_a1),
.register_a2(register_a2),
.register_a3(register_a3),
.register_we3(register_we3),
.register_wd3(register_wd3),
.register_rd1(register_rd1),
.register_rd2(register_rd2));

// Testbench
reg[31:0] i_counter, reg_counter, mem_counter;
initial begin
// Выполняем 2023 тактов
for (i_counter = 0; i_counter < 2023; i_counter = i_counter+1) begin
#5
clk = 1;
#5
clk = 0;
end
// Дампим регистры
for (reg_counter = 0; reg_counter < 32; reg_counter = reg_counter+1) begin
$display("Register: %d, value: %d", reg_counter, cpu_register.mem[reg_counter]);
end
// Дампим память данных
for (mem_counter = 0; mem_counter < 64; mem_counter = mem_counter+1) begin
$display("Addr: %d, value: %d", mem_counter*4, cpu_data_memory.ram[mem_counter]);
end
end
endmodule
Loading

0 comments on commit 9f4fa21

Please sign in to comment.