libvirt-0001/0002 + xen-0001: cpu_x86 g_strv_contains O(F×A) + x86FeatureFind O(C×F) + credit2 balance_load O(V²); 21+11 PASS; count 608→611
This commit is contained in:
parent
87099aaaac
commit
47a312b0c7
26 changed files with 1308 additions and 4 deletions
187
defects/xen/unit/Xen0001CreditBalanceLoadAlgorithm.java
Normal file
187
defects/xen/unit/Xen0001CreditBalanceLoadAlgorithm.java
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
package defects.xen.unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* xen-0001: Xen credit2 balance_load() O(V²) VCPU swap-search.
|
||||
*
|
||||
* Models the inner double-loop in balance_load() (credit2.c:2835–2861).
|
||||
* The defective version iterates all VCPUs on lrqd × orqd to find the best
|
||||
* (push, pull) swap pair. The fixed version maintains runqueue lists sorted
|
||||
* by avgload so the best pair is found in O(V) time.
|
||||
*/
|
||||
public class Xen0001CreditBalanceLoadAlgorithm {
|
||||
|
||||
public static class Vcpu {
|
||||
final int id;
|
||||
long avgload;
|
||||
boolean migratable;
|
||||
|
||||
Vcpu(int id, long avgload, boolean migratable) {
|
||||
this.id = id;
|
||||
this.avgload = avgload;
|
||||
this.migratable = migratable;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SwapPair {
|
||||
final Vcpu push; // from lrqd
|
||||
final Vcpu pull; // from orqd (may be null for push-only)
|
||||
final long loadDelta; // abs delta after swap
|
||||
|
||||
SwapPair(Vcpu push, Vcpu pull, long loadDelta) {
|
||||
this.push = push;
|
||||
this.pull = pull;
|
||||
this.loadDelta = loadDelta;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Defective: O(V²) — full cross-product as in credit2.c
|
||||
// -----------------------------------------------------------------------
|
||||
public static class DefectiveBalanceLoad {
|
||||
public int comparisons;
|
||||
|
||||
public SwapPair findBestSwap(List<Vcpu> lrqdSvc, List<Vcpu> orqdSvc,
|
||||
long lLoad, long oLoad) {
|
||||
comparisons = 0;
|
||||
SwapPair best = null;
|
||||
long bestDelta = Math.abs(lLoad - oLoad);
|
||||
|
||||
for (Vcpu push : lrqdSvc) {
|
||||
if (!push.migratable) continue;
|
||||
|
||||
for (Vcpu pull : orqdSvc) {
|
||||
comparisons++;
|
||||
if (!pull.migratable) continue;
|
||||
|
||||
// delta after swapping push→orqd and pull→lrqd
|
||||
long newL = lLoad - push.avgload + pull.avgload;
|
||||
long newO = oLoad - pull.avgload + push.avgload;
|
||||
long delta = Math.abs(newL - newO);
|
||||
if (delta < bestDelta) {
|
||||
bestDelta = delta;
|
||||
best = new SwapPair(push, pull, delta);
|
||||
}
|
||||
}
|
||||
|
||||
// push-only consideration
|
||||
long newL = lLoad - push.avgload;
|
||||
long newO = oLoad + push.avgload;
|
||||
long delta = Math.abs(newL - newO);
|
||||
if (delta < bestDelta) {
|
||||
bestDelta = delta;
|
||||
best = new SwapPair(push, null, delta);
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Fixed: O(V) — pick heaviest push + lightest pull from sorted lists
|
||||
// -----------------------------------------------------------------------
|
||||
public static class FixedBalanceLoad {
|
||||
public int comparisons;
|
||||
|
||||
/**
|
||||
* Both lrqdSvc and orqdSvc are assumed sorted descending by avgload
|
||||
* (maintained at VCPU assign/weight-update time).
|
||||
* Scan from highest-weight end for push, lowest-weight end for pull.
|
||||
*/
|
||||
public SwapPair findBestSwap(List<Vcpu> lrqdSvcSorted,
|
||||
List<Vcpu> orqdSvcSorted,
|
||||
long lLoad, long oLoad) {
|
||||
comparisons = 0;
|
||||
long currentDelta = Math.abs(lLoad - oLoad);
|
||||
|
||||
// Find heaviest migratable push candidate
|
||||
Vcpu bestPush = null;
|
||||
for (Vcpu v : lrqdSvcSorted) {
|
||||
comparisons++;
|
||||
if (v.migratable) { bestPush = v; break; }
|
||||
}
|
||||
if (bestPush == null) return null;
|
||||
|
||||
// Find lightest migratable pull candidate (from end of sorted list)
|
||||
Vcpu bestPull = null;
|
||||
for (int i = orqdSvcSorted.size() - 1; i >= 0; i--) {
|
||||
comparisons++;
|
||||
Vcpu v = orqdSvcSorted.get(i);
|
||||
if (v.migratable) { bestPull = v; break; }
|
||||
}
|
||||
|
||||
// Evaluate push+pull swap
|
||||
SwapPair best = null;
|
||||
if (bestPull != null) {
|
||||
long newL = lLoad - bestPush.avgload + bestPull.avgload;
|
||||
long newO = oLoad - bestPull.avgload + bestPush.avgload;
|
||||
long delta = Math.abs(newL - newO);
|
||||
if (delta < currentDelta) {
|
||||
best = new SwapPair(bestPush, bestPull, delta);
|
||||
currentDelta = delta;
|
||||
}
|
||||
}
|
||||
// Evaluate push-only
|
||||
long newL = lLoad - bestPush.avgload;
|
||||
long newO = oLoad + bestPush.avgload;
|
||||
long delta = Math.abs(newL - newO);
|
||||
if (delta < currentDelta) {
|
||||
best = new SwapPair(bestPush, null, delta);
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/** Build a list of V VCPUs with loads evenly spread, all migratable. */
|
||||
public static List<Vcpu> buildSvcList(int count, long baseLoad, boolean sorted) {
|
||||
List<Vcpu> list = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
list.add(new Vcpu(i, baseLoad + i * 10, true));
|
||||
}
|
||||
if (sorted) {
|
||||
list.sort((a, b) -> Long.compare(b.avgload, a.avgload));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/** Compute total load for a VCPU list. */
|
||||
public static long totalLoad(List<Vcpu> svc) {
|
||||
return svc.stream().mapToLong(v -> v.avgload).sum();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("xen-0001: credit2 balance_load O(V^2) vs O(V)");
|
||||
System.out.println("=".repeat(55));
|
||||
|
||||
int[] sizes = {10, 50, 100, 200};
|
||||
DefectiveBalanceLoad defective = new DefectiveBalanceLoad();
|
||||
FixedBalanceLoad fixed = new FixedBalanceLoad();
|
||||
|
||||
System.out.printf("%-8s %-12s %-12s %-8s%n",
|
||||
"V/rqd", "Defect ops", "Fixed ops", "Ratio");
|
||||
|
||||
for (int v : sizes) {
|
||||
List<Vcpu> lrqd = buildSvcList(v, 100, false);
|
||||
List<Vcpu> orqd = buildSvcList(v, 50, false);
|
||||
long lLoad = totalLoad(lrqd);
|
||||
long oLoad = totalLoad(orqd);
|
||||
|
||||
defective.findBestSwap(lrqd, orqd, lLoad, oLoad);
|
||||
int defectOps = defective.comparisons;
|
||||
|
||||
List<Vcpu> lrqdSorted = buildSvcList(v, 100, true);
|
||||
List<Vcpu> orqdSorted = buildSvcList(v, 50, true);
|
||||
fixed.findBestSwap(lrqdSorted, orqdSorted, lLoad, oLoad);
|
||||
int fixedOps = fixed.comparisons;
|
||||
|
||||
double ratio = (double) defectOps / fixedOps;
|
||||
System.out.printf("%-8d %-12d %-12d %.1f×%n",
|
||||
v, defectOps, fixedOps, ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue