---
# System prepended metadata

title: Architektury systemów komputerowych

---

# Architektury systemów komputerowych

## Lista 10.

### Zadanie 1.

- $T_{avg seek} = 576 / 24 / 3 \cdot 1ms = 8ms$
- $T_{avg rotation} = 1/7200RPM \cdot 60s/1min / 2 = 4.17ms$
- $T_{transfer} = 1/7200RPM \cdot 60s/1min / 32000 = 0.000026ms$
- $T_{access} = 8ms + 4.17ms + 0.000026ms = 12.17ms$

## Lista 7.

### Zadanie 5.
```cpp
union elem {
    struct {
        long *p;
        long y;
    } e1;
    struct {
        long x;
        union elem *next;
    } e2;
};

elem* f(elem *el){
    elem *next = el->e2.next;
    el->e2.x = *(next->e1.p) - next->e1.y;
    return next;
}
```

### Zadanie 6.
```cpp
typedef struct A {
    ll u[2];
    ll *v;
} SA;
typedef struct B {
    ll p[2];
    ll q;
} SB;

SB eval(SA s){
    SB ret = SB();
    ret.p[0] = s.u[1] * *(s.v);
    ret.p[1] = s.u[0] - *(s.v);
    ret.q = s.u[0] - s.u[1];
    return ret;
}

ll wrap(ll x, ll y, ll z){
    SB s = eval({x,y,&z});
    return s.q * (s.p[0] + s.p[1]);
}
```

### Zadanie 7.
```cpp
struct P{
    long sz;
    float *tab;
};

float puzzle7(P *p, float x){
    long sz = p->sz;
    float* tab = p->tab;
    float ret = 0;
    float bs = 1;
    for(int i=0;i<sz;i++){
        ret = bs * tab[i];
        bs *= x;
    }
    return ret;
}
```

### Zadanie 8.
```
Base::doit(int):
        movl    %esi, %eax
        subl    8(%rdi), %eax
        ret
Derived::doit(int):
        movl    8(%rdi), %eax
        imull   %esi, %eax
        ret
doit(Base*):
        movq    (%rdi), %rax
        movl    $1, %esi
        movq    (%rax), %rax
        jmp     *%rax
main:
        pushq   %rbx
        subq    $32, %rsp
        movq    %rsp, %rdi
        movq    $vtable for Base+16, (%rsp)
        movl    $10, 8(%rsp)
        movl    $21, 24(%rsp)
        movq    $vtable for Derived+16, 16(%rsp)
        call    doit(Base*)
        leaq    16(%rsp), %rdi
        movl    %eax, %ebx
        call    doit(Base*)
        addq    $32, %rsp
        addl    %ebx, %eax
        popq    %rbx
        ret
vtable for Base:
        .quad   0
        .quad   0
        .quad   Base::doit(int)
vtable for Derived:
        .quad   0
        .quad   0
        .quad   Derived::doit(int)
```

Wielomian
## Lista 6.

### Zadanie 1.
```cpp
#include <iostream>
#include <algorithm>
using namespace std;
using ll = long long;

extern "C" long pointless(long n, long* p);

long pointless2(long n, long* p) {
    if (n == 0)
        return 0;

    long result2 = 0;
    long result = pointless2(n+n, &result2);
    result += result2;
    n += result;
    *p = n;
    return result;
}

int main(){
    for(int i=0;i<100;i++){
        long res = 0;
        cout << pointless2(i, &res) << " ";
        res = 0;
        cout << pointless(i, &res) << "\n";
    }

    return 0;
}
```

### Zadanie 2.
```cpp
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
using ll = long long;

struct T{
    ll a;
    ll b;
    ll c;
};

ll a[5] = {6,7,8,10,9};

extern "C" T puzzle2(ll* a, ll n);

T puzzle2hand(ll* a, ll n){
    T ret;
    ll sum = 0;
    ll maxi = LONG_MIN;
    ll mini = LONG_MAX;
    for(ll i=0;i<n;i++){
        ll rcx = a[i];
        mini = min(mini, a[i]);
        maxi = max(maxi, a[i]);
        sum += a[i];
    }
    ret.a = mini;
    ret.b = maxi;
    ret.c = sum / n;
    return ret;
}

int main(){

    T res = puzzle2(&a[0], 5);
    T res2 = puzzle2hand(&a[0], 5);
    
    cout << res.a << " " << res.b << " " << res.c << "\n";
    cout << res2.a << " " << res2.b << " " << res2.c << "\n";

    return 0;
}
```

### Zadanie 3.
```cpp
#include <iostream>
using namespace std;

int64_t fd(int64_t x){
    return x+5;
}

int64_t f60(int64_t x){
    return x*8;
}

int64_t f61(int64_t x){
    return x*8;
}

int64_t f62(int64_t x){
    return (x<<4) - x;
}

int64_t f64(int64_t x){
    return x >> 3;
}

int64_t f65(int64_t x){
    return x*x; 
}

int64_t (*arr[])(int64_t) = {f60, f61, f62, fd, f64, f65};

int64_t switch_prob(int64_t x, int64_t n){
    if(60 <= n && n <= 65){
        return arr[n-60](x);
    }
    return fd(x);
}

int main(){
    return 0;
}
```

### Zadanie 4.
```cpp
#include <iostream>
using namespace std;
using ll = long long;

extern "C" ll M(ll x);
extern "C" ll F(ll x);

ll Fhand(ll x);

ll Mhand(ll x){
    return (x ? x - Fhand(Mhand(x-1)) : 0);
}

ll Fhand(ll x){
    return (x ? x - Mhand(Fhand(x-1)) : 1);
}

int main(){
    for(int i=1;i<=10;i++){
        cout << i << " " << M(i) << " " << Mhand(i) << " " <<
        F(i) << " " << Fhand(i) << "\n";
    }
    
    return 0;
}
```

## Lista 5.

### Zadanie 1.

```asm
.section .text
.global addu

addu:
    add %rdi, %rsi
    sbb %rax, %rax
    or %rsi, %rax
    ret
```

### Zadanie 2.

```asm
.section .text
.global cmp

cmp:
    sub %rsi, %rdi
    sbb %rax, %rax
    neg %rdi
    adc %rax, %rax
    ret
```

### Zadanie 3.

```cpp
int puzzle(long x, unsigned n){
    int eax = 0;
    if(n == 0) return n;
    for(int edx=0;edx!=n;edx++){
        eax += x & 1;
        x /= 2;
    }
    return eax;
}
```
Popcount na pierwszych na bitach (najniższych)

### Zadanie 4.

```cpp
long puzzle2(char *s, char *d){
    char* rax = d;
    do{
        char* rdx = s;
        char c;
        do{
            c = *(rdx++);
            if(c == 0){
                return rax - d;
            }
        }while(c != *rax);
        rax++;
    }while(1);
}
```
Liczenie najdłuższego prefiksu słowa d, które jest podsłowem słowa s.

### Zadanie 5.

```cpp
#include <iostream>
using namespace std;

uint32_t puzzle3(uint32_t n, uint32_t d){
    uint64_t n2 = n;
    uint64_t d2 = d;
    d2 <<= 32;
    uint32_t edx = 32;
    uint32_t ecx = 0x80000000;
    uint32_t eax = 0;
    do{
        n2 += n2;
        int64_t r8 = n2;
        r8 -= d2;
        if(r8 >= 0){
            eax |= ecx;
            n2 = r8;
        }
        ecx >>= 1;
        edx--;
    }while(edx);
    return eax;
}


int main(){
    for(int i=1;i<=20;i++){
        for(int j=1;j<=20;j++){
            cout << puzzle3(i,j) << " ";
        }
        cout << "\n";
    }

    return 0;
}
```
Dzielenie całkowite liczb nieujemnych.

### Zadanie 6.

```cpp
#include <iostream>
using namespace std;

uint32_t puzzle4(long *a, long v, uint64_t s, uint64_t e){
    uint64_t mid = (e-s)/2 + s;
    if(s > e) return -1;
    uint64_t r8 = a[mid];
    if(r8 == v) return mid;
    if(r8 > v) return puzzle4(a, v, s, mid-1);
    return puzzle4(a, v, mid+1, e);
}

long arr[] = {1, 5, 7, 8};

int main(){
    int i = puzzle4(&arr[0], 7, 0, 3);

    cout << i << "\n";

    return 0;
}
```

### Zadanie 7.

```cpp
#include <iostream>
using namespace std;

int64_t switch_prob(int64_t x, int64_t n){
    switch(n){
        case 60:
        case 61:
            return x * 8;
        case 64:
            return x >> 3;
        case 62:
            x = (x << 4) - x;
        case 65:
            x = x * x;
        default:
            return x + 75;
    }
}

int main(){
    return 0;
}
```

## Lista 4.

### Zadanie 1.

- 256
- 19
- 264
- 255
- 171
- 17
- 255
- 17
- 17

### Zadanie 2.

- 0x100 = 256
- %rdx = -10
- %rax = 16
- 0x110 = 18
- %rcx = 0
- 0x108 = 43776
- %rdx = 16
- %rdx = 22

### Zadanie 3.

```cpp
#define ALPHA 0.7
#define Q16 ((uint16_t)(ALPHA * (1 << 16)))

int16_t exp_smooth(int16_t xi, int16_t s_prev, uint16_t alpha) {
    int32_t si = (int32_t)alpha * xi + ((1 << 16) - alpha) * s_prev;
    return (int16_t)(si >> 16);
}

volatile int16_t x[] = {1, 4, 3, 2};
int16_t s[] = {0, 0, 0, 0};

int main() {
    s[0] = x[0];

    for (int i = 1; i <= 10; ++i) {
        exp_smooth(x[i], s[i-1], Q16);
    }

    return 0;
}
```

## Zadanie 4.

```cpp
long decode(long x, long y){
    long z = x + y;
    y ^= z;
    x ^= z;
    z = x & y;
    return z >> 63;
}
```

## Zadanie 5.

```
ror $24,%edi
rorq $8,%rdi
ror $24,%edi
rorq $8,%rdi
ror $24,%edi
rorq $8,%rdi
ror $24,%edi
rorq $8,%rdi
mov %edi,%eax
```

## Zadanie 6.

```
movq %rsi,%rax
addq %rcx,%rax
adcq %rdi,%rdx
```

## Lista 3.

### Zadanie 1.

```cpp
#include <iostream>
#include <bitset>
#include <cassert>
using namespace std;

int64_t third = 0x55555556;

int64_t div3(int64_t x){
    return ((x * third) >> 32) - (-1 & x>>63);
}

int main(){
    for(int32_t i=-1e9;i<=1e9;i++){
        assert(div3(i) == (i < 0 ? -abs(i)/3 : i/3));
    }
}
```

### Zadanie 2.

```cpp
#include <iostream>
#include <bitset>
using namespace std;

int k = 2;
int n = 4;
uint64_t a[4] = {1LL<<31, 1LL<<31, 1LL<<30, 1LL<<30};
uint64_t b[4] = {1LL<<31, 1LL<<30, 1LL<<31, 1LL<<30};;

int main(){
    cin.tie(0);
    ios_base::sync_with_stdio(0);

    uint64_t tot = 0;
    uint64_t tot2 = 0;

    for(int i=0;i<n;i++){
        uint64_t res = (a[i] > b[i] ? (a[i]-b[i])*(a[i]-b[i]) : (b[i]-a[i])*(b[i]-a[i]));
        tot += res & 0x0000FFFF;
        tot2 += res >> 32;
    }
    tot2 += tot >> 32;
    
    cout << bitset<32>(tot2 >> k) << "\n";

    return 0;
}
```

### Zadanie 3.

$0 01100 0100000000_{16bit float} = 0.15625$

![obraz](https://hackmd.io/_uploads/rkfl1bSpa.png)
Dla normalnych floatów pewnie podobnie
subnormal min - $2^{-150}$?
positive min - $2^{-126}$
maximum num - $(2-2^{-23})*2^{127}$

### Zadanie 4.

### Zadanie 5.

1. TAK
2. NIE, MIN_INT i -1
3. TAK
4. NIE, kontrprzykład: -2147483625 -2147483415 -2147481315
5. NIE, kontrprzykład: 0 1

### Zadanie 6.

```cpp
#include <iostream>
using namespace std;

uint32_t sign(uint32_t x){
    return x ^ 1<<31;
}

uint32_t log(uint32_t x){
    return (x>>23)-127 & 0x000000FF;
}

uint32_t eq(uint32_t x, uint32_t y){
    return ((x|y)==0x80000000) & (x==y);
}

int main(){
    float a = 19.5;
    int x = * ( int * ) &a;
    cout << log(x) << "\n";
}
```
![obraz](https://hackmd.io/_uploads/BJIeQXSaT.png)
![obraz](https://hackmd.io/_uploads/r1A-m7rTp.png)

### Zadanie 7.

```cpp
uint32_t shift(uint32_t x, int32_t k){
    int32_t e = (x>>23&0x000000FF) - 127;
    uint32_t man = 0x007FFFFF;
    uint32_t exp = 0x7F800000;
    uint32_t sgn = 0x80000000;
    if(k >= 0){
        k = min(k, 255-e);
        x += k << 23;
    }
    else{
        int32_t k2 = -k;
        if(k2 > e+127){
            int32_t s = x & sgn;
            x &= ~exp | ~sgn;
            x >>= k2-e-127;
            x |= s;
        }
        else{
            x -= k2 << 23;
        }
    }
    return x;
}
```

### Zadanie 8.

```cpp
#include <iostream>
#include <iomanip>
#include <bitset>
using namespace std;

int32_t int2float(int32_t x){
    if(x == 0) return 0;
    uint32_t sgn = x < 0;
    x = abs(x);
    uint32_t lb = __builtin_clz(x);
    uint32_t exp = 31 - lb;
    uint32_t man = ((uint32_t)(x & ((1<<(exp+1))-1)) << (32 - exp)) >> 9;
    uint32_t guard = (exp >= 23 ? (x >> exp-23 & 1) : 0);
    uint32_t round = (exp >= 24 ? (x >> exp-24 & 1) : 0);
    uint32_t stick = (exp >= 25 ? (x & (1<<(exp-24))-1) > 0 : 0);
    if(round && (guard || stick)) man++;
    if(man >> 23){
        man &= (1<<23)-1;
        man >>= 1;
        exp++;
    }
    return (sgn << 31) | ((exp+127) << 23) | man;
}

int main(){

    int32_t x = int2float((1<<30)-1);
    cout << (1<<30)-1 << "\n";
    cout << *(float*)(&x) << "\n";

    return 0;
}
```

### Zadanie 9.

```cpp
#include <iostream>
using namespace std;

int32_t float2int(int32_t f) {
    int32_t s = f >> 31; /* -1 jeśli znak był ujemny */
    int32_t e = (f >> 23 & 255) - 127; /* wykładnik po odjęciu bias */
    uint32_t m = f << 8 | 0x80000000; /* mantysa 1.xxx... dosunięta do lewej */
    m = (e > 31 ? 0x80000000 : (m>>max(0,(31-e))));
    return m * (2*s+1);
}

int main(){
    float x = 0x80000000;

    cout << float2int(*(int32_t*)&x) << "\n";

    return 0;
}
```

### Zadanie 10.

## Lista 2.

### Zadanie 1.

- NIE, bo $INT\_MIN < 0$ i $INT\_MIN - 1 > 0$
- TAK, jeśli pierwszy warunek jest spełniony to reprezentacją tej liczby po przesunięciu będzie $111000000\dots_2$
- NIE, $(2^{15} + 2^{14})^2 < 0$
- TAK, $0$ spełnia, wszystkie oprócz $INT\_MIN$a też i sam $INT\_MIN$ tak samo 
- TAK, bo tak powiedziałem
- NIE, bo $0$
- TAK, typy signed i unsigned dodają się tak samo, przy porównaniu następuje konwersja typu (bez zmiany reprezentacji)
- TAK, sumarycznie $y$ i $\neg y$ upraszczają się do mnożenia przez $-1$

### Zadanie 2.

```cpp
x ^= y ^= x ^= y;
```

### Zadanie 3.

```cpp
int32_t overflowcheck(int32_t x, int32_t y){
    return (~(x^y)&(s^x))>>31&1;
}
```

### Zadanie 4.

```cpp
uint32_t simdadd(uint32_t x, uint32_t y){
    return (x & 0x7F7F7F7F) + (y & 0x7F7F7F7F) ^ (x ^ y) & 0x80808080;
}

uint32_t simdsub(uint32_t x, uint32_t y){
    return ~((x ^ y | 0x7F7F7F7F) ^ (x | 0x80808080) - (y & 0x7F7F7F7F));
}
```

### Zadanie 5.

```cpp
int32_t threefourths(int32_t x){
    return ((x>>2)<<1) + (x>>2) + ((((x&3)<<1)+(x&3))>>2);
}
```

### Zadanie 6.

```cpp
uint32_t lesssigned(int32_t x, int32_t y){
    return (~y&x|(~y|x)&(x^1<<31)-(y^1<<31))>>31&1;
}

uint32_t lessunsigned(uint32_t x, uint32_t y){
    return (~x&y|(~x|y)&x-y)>>31&1;
}
```

### Zadanie 7.

```cpp
int32_t abs(int32_t x){
    return ~x>>31 & x | x>>31 & -x;
}
```

### Zadanie 8.

```cpp
int32_t sgn(int32_t x){
    return ~x>>31 & 1 & ~(~x>>31 & x-1>>31) | x>>31 & -1; 
}
```

### Zadanie 9.

```cpp
int32_t oddpop(uint32_t x){
    x = (x & 0x55555555) + ((x>>1) & 0x55555555);
    x = (x & 0x33333333) + ((x>>2) & 0x33333333);
    x = (x & 0x0F0F0F0F) + ((x>>4) & 0x0F0F0F0F);
    x = (x & 0x00FF00FF) + ((x>>8) & 0x00FF00FF);
    x = (x & 0x0000FFFF) + ((x>>16) & 0x0000FFFF);
    return (x & 1);
}
```