[apt-proxy] dd gebruikt 100% cpu

Pagina: 1
Acties:

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05-2025
Ik heb op mijn debian woody servertje (100 Mhz 486) apt-proxy geinstalleerd. Als ik op een eerste computer die deze proxy gebruikt 'apt-get upgrade' doe, worden de packages trager (max 20 ipv 75 kb/s) binnen gehaald dan als ik niet via apt-proxy download.
Het probleem is dat dd (wordt door apt-proxy gebruikt) erg veel resources gebruikt en dat mij cpu usage naar 100% gaat. In het apt-proxy script wordt dd aangeroepen met:
code:
1
dd ibs=1 obs=16384 skip=$2 count=$3 if="$1" 2>/dev/null

Kan ik mijn systeemload omlaag brengen door bijv. de ibs waarde omhoog te doen? Heeft dat invloed op de files die opgeslagen worden? Ik neem aan dat de schrijver van apt-proxy toch niet (helemaal) voor niets voor deze waardes heeft gekozen...

  • Wilke
  • Registratie: December 2000
  • Laatst online: 23:50
Sir Isaac schreef op 03 mei 2004 @ 21:57:
In het apt-proxy script wordt dd aangeroepen met:
code:
1
dd ibs=1 obs=16384 skip=$2 count=$3 if="$1" 2>/dev/null
Aw, wat slecht! Kopieren met 1 byte per keer in de input buffer :X

Maar er is helaas wel een reden voor denk ik: 'skip' doet dit:
code:
1
2
skip=blocks 
  Skip blocks ibs-byte blocks in the input file before copying.


Dus hij slaat de eerste $2 bytes uit de input-buffer over. Maar als je 'ibs' op iets anders dan 1 zet, kun je het aantal bytes alleen in een veelvoud van 'ibs' opgeven. Dat zal dus vast fout gaan tenzij $2 == 0. Je zou eens kunnen testen of $2 op die plek in jouw geval gewoonlijk 0 is, want dan kun je namelijk net zo makkelijk 'ibs=16384' opgeven [disclaimer] denk ik :+ [/disclaimer]

offtopic:
Dit brengt me op allerlei foute ideeen. Je zou met 'factor' kunnen kijken naar de kleinste deler, en dan nemen ibs=$2/$kleinstedeler en skip=$kleinstedeler:

Dus zo:
$kleinstedeler=`factor $2 | awk '{print $1}'`
dd ibs=$[$2/$kleinstedeler] obs=16384 skip=$kleinstedeler count=$3 if="$1" 2>/dev/null

Is wel een ziek idee moet ik toegeven 8)7

[ Voor 21% gewijzigd door Wilke op 03-05-2004 22:58 ]


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 21:48

odysseus

Debian GNU/Linux Sid

Wilke schreef op 03 mei 2004 @ 22:45:
offtopic:
Dit brengt me op allerlei foute ideeen. Je zou met 'factor' kunnen kijken naar de kleinste deler, en dan nemen ibs=$2/$kleinstedeler en skip=$kleinstedeler:

Dus zo:
$kleinstedeler=`factor $2 | awk '{print $1}'`
dd ibs=$[$2/$kleinstedeler] obs=16384 skip=$kleinstedeler count=$3 if="$1" 2>/dev/null

Is wel een ziek idee moet ik toegeven 8)7
Leuk idee :P. Wel nog even dat dollarteken voor 'kleinstedeler' in het eerste commando weghalen als je wilt dat het werkt ;). Daarnaast verwacht ik dat cut wat efficiënter is:
code:
1
kleinstedeler=`factor $2 | cut -f 2 -d\ `

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Verwijderd

Wat jullie zoeken is de grootste gemene deler (engels GCD: greatest common divisor); en dat is niet per ce de grootste priemfactor (hetgeen factor uitrekent).

Voorbeeld: getallen 6 en 12 leveren 6 als GCD op, maar 3 als grootste priemfactor.

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 21:48

odysseus

Debian GNU/Linux Sid

Wat je eigenlijk zoekt zijn twee getallen waarvoor het volgende geldt:
• beide zijn integers
• vermenigvuldigd zijn ze skip
• één van de getallen is ibs
ibs is zo groot mogelijk

Je gaat skip ontleden in termen (daar komt dan een reeks priemgetallen en tweeën uit). Vervolgens heb je een kleinste getal (dat zal het eerst teruggeven getal van factor zijn) en eventueel andere getallen. De meest efficiënte oplossing is die met het kleinste getal dat factor teruggeeft bij skip, want dat levert een zo groot mogelijke ibs op :).

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Verwijderd

Je wilt count blocks van ibs bytes copieren, en daarbij skip blocks van ibs bytes overslaan.

Je copieert dus count * ibs bytes;
Je overspringt skip * ibs bytes.

In het bestaande geval is ibs gelijk aan 1, dus je copieert count bytes en overspringt skip bytes. Je kunt ibs nu dus zo groot mogelijk krijgen door de grootste gemene deler van count en skip te bepalen.

Daarbij is een GCD bepalen volgens de methode van Euclides vele malen sneller dan ontbinden in priemen. (Het eindresultaat is het zelfde.)

[ Voor 6% gewijzigd door Verwijderd op 04-05-2004 21:15 ]


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 21:48

odysseus

Debian GNU/Linux Sid

Nu zie ik wat je bedoelt :). Het hangt er een beetje van af hoe je de manpage van dd leest:
count=BLOCKS copy only BLOCKS input blocks
ibs=BYTES read BYTES bytes at a time
skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input
Bij count gaat het niet over 'ibs-sized blocks', maar over 'input blocks' - bij skip is het precies andersom. De kans is aanwezig dat die input blocks elk ibs bytes groot zijn, maar dat wordt dus niet helemaal duidelijk. Is dat zo, dan heb jij gelijk, maar dan vind ik de manpage niet honderd procent duidelijk :).

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Verwijderd

odysseus schreef op 04 mei 2004 @ 22:41:
Bij count gaat het niet over 'ibs-sized blocks', maar over 'input blocks' - bij skip is het precies andersom. De kans is aanwezig dat die input blocks elk ibs bytes groot zijn, maar dat wordt dus niet helemaal duidelijk. Is dat zo, dan heb jij gelijk, maar dan vind ik de manpage niet honderd procent duidelijk :).
Ik heb zo'n donkerbruin vermoeden dat ibs Input Block Size betekent ;)

edit:
en dat de manpage expliciet ibs-sized bij skip vermeldt om het onderscheid met seek duidelijk te maken, die obs-sized blocks in de output skipt.

[ Voor 21% gewijzigd door Verwijderd op 05-05-2004 01:54 ]


  • Wilke
  • Registratie: December 2000
  • Laatst online: 23:50
mietje schreef op 04 mei 2004 @ 17:29:[/b]
Wat jullie zoeken is de grootste gemene deler (engels GCD: greatest common divisor); en dat is niet per ce de grootste priemfactor (hetgeen factor uitrekent).

Voorbeeld: getallen 6 en 12 leveren 6 als GCD op, maar 3 als grootste priemfactor.[/quote]

Weet ik, maar AFAIK is er geen standaar UNIX-progje wat dat doet.

Trouwens, ik zoek niet de grootste priemfactor, maar juist de kleinste priemfactor (ook dat rekent 'factor' uit).

Dus als jij 'factor 12' intikt krijg je '12: 2 2 3', kortom '2` als kleinste deler, dus 6 als blocksize en 2 bij skip. Dat was dus precies mijn idee ;)

Of 'cut' efficienter is dan 'awk' weet ik niet, maar ach. Moet trouwens ook het tweede veld zijn zie ik nu, niet het eerste.

[ Voor 58% gewijzigd door Wilke op 05-05-2004 04:25 ]


Verwijderd

Wilke schreef op 05 mei 2004 @ 04:19:
Weet ik, maar AFAIK is er geen standaar UNIX-progje wat dat doet.
Dat komt omdat het zeer gemakkelijk zelf te implementeren is:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

function gcd () {
    local A=$1
    local B=$2
    local SW
    while [ $B -gt 0 ]; do
        SW=$(($A % $B))
        A=$B
        B=$SW
    done
    echo $A
}

gcd $1 $2
Trouwens, ik zoek niet de grootste priemfactor, maar juist de kleinste priemfactor (ook dat rekent 'factor' uit).

Dus als jij 'factor 12' intikt krijg je '12: 2 2 3', kortom '2` als kleinste deler, dus 6 als blocksize en 2 bij skip. Dat was dus precies mijn idee ;)
Ik denk dat zowel skip als count met ibs-sized blocks werken, je zult dus een ibs moeten uitrekenen die een deler is van zowel skip als count.

edit:
Waarom ik dit denk kan ik eenvoudig demonstreren, we doen gewoon een dd rechtstreeks vanaf de prompt :)
code:
1
echo "aabbccdd" | dd ibs=2 skip=2 count=2 2>/dev/null

ibs is hier 2, en omdat skip gelijk is aan 2 zal dd beginnen te copieren vanaf de eerste 'c', oftewel vanaf byte skip * ibs + 1; daarover zijn we het eens.

Als ik gelijk heb copieert dd vervolgens count * ibs bytes, en is de output 'ccdd', als jij gelijk hebt copieert dd vervolgens count bytes en is de output 'cc'.

[ Voor 33% gewijzigd door Verwijderd op 05-05-2004 13:37 ]

Pagina: 1