[P4] L2 gyorsulás
Kitlei Róbert
kitlei at elte.hu
Fri Mar 11 12:08:34 CET 2016
Sziasztok!
Tegnap elkezdtem javítani az L2-nk teljesítményét. Néhány próbálkozásom
nem járt sikerrel, pl. a likely/unlikely semmit sem javított, akárhová
is tettem be; leírom, ami működött.
1. (3.7 GBps) Kezdetnek azt néztem meg, hogy mi történik akkor (a
performance branch-ből kiindulva, a test_dpdk2.sh-t futtatva), ha
lekapcsolom a handle_packet-et, és csak a dpdk_send_packet-tel küldöm ki
változatlanul a beérkező csomagokat. Ekkor a "gyári" l2fwd-hoz hasonlóan
telíteni kellett volna a 10 GBps-es csatornát, de csak 5.2 GBps-et
mutatott a rendszer. Kiderült, hogy a burst használata esszenciális; már
nem emlékszem, miért kapcsoltam át r198-ban egyenkénti csomagküldésre,
de ha visszaírom olyanra a dpdk_send_packet-et, mint az
l2fwd_send_burst, akkor rögtön nő a teljesítmény, handle_packet nélkül
ki is maxolja az elérhető 10 gigát.
2. (5.2 GBps) A kódban ezenkívül egy dolog lassít jelentősen: a
dataplane.c-ben az lpm_lookup meghívása. Ha ezt kiiktatom, ismét 10
GBps-sel megyünk; ha meghagyom, a lookup kódjának a belsejében a memcpy
a főbűnös, ahogy azt mindenki korábban gyanította. Mivel a konkrét
esetben t->key_size == 14, ha a levél alján látható módon külön kezelem
ezt az esetet, és memcpy helyett simán átmásolom a tartalmat, akkor
hirtelen felszökik a sebesség. Arra már nem volt időm, hogy a másolást
máshogy is kipróbáljam, lehet, hogy bájtoknál nagyobb egységekkel
dolgozva még adódik valamekkora gyorsulás. Illetve, ami még ebben a
kódrészletben van, és lehet, hogy gyorsítható, az maga az rte_lpm_lookup
hívás, de azt nyilván kevésbé szeretnénk újraimplementálni.
Mivel ez egy speciális változtatás (a key_size értéke csak pont ebben a
példában fix 14), a másolást ennél általánosabban kell elintézni. Lehet,
hogy egy ügyes Duff's device megoldja, de az sem lehetetlen, hogy
valamilyen szinten hint-elni kell a fordítás során a programot: vagy a
P4 szintje alatt, vagy akár ez lehet egy javaslatunk a P4 kiterjesztésére.
3. (8.9 GBps) Ami még -- talán -- egy kicsit javít a futási sebességen,
az, ha a DPDK-t nem GCC-vel, hanem clang-gal fordítom. Enélkül a
sebesség első számjegye 8-as fölé nem ment, ezzel szinte mindig 9-es
volt, de ez csak akkora különbség, ami néha ingadozásként is előjön. Még
egy lehetőség, amit már nem értem rá próbálgatni: hátha a DPDK-t
EXTRA_CFLAGS='-O3' kapcsolóval fordítva gyorsabb lesz. A saját kódunk
GCC-vel és clang-gal egyformán teljesít, a jobb hibaüzenetek miatt
lehet, hogy érdemes áttérni clang-ra.
4. (9.1 GBps) Jelenleg itt tartunk. Mivel ez a jelenlegi konfiguráció
maximumától (10 GBps) nincsen túl messze, meg kell kérni a srácokat,
hogy adjanak hozzáférést a 40 GBps-es (vagy 100-as) kártyás gépekhez is,
mert még 10% gyorsulás, és már nem látjuk, mennyire jó a kód
teljesítménye. Peti, utána tudsz kérdezni?
5. A big/little endian konverzió koncepcionálisan persze fontos, hogy
hová kerül a kódban, de a teljesítményt nem valószínű, hogy érdemileg
befolyásolja: egyetlen bswap utasításra fordul le.
Robi
--------------------------------------------
A gyorsuláshoz ezt toldottam be az lpm_lookup elágazásának első ágaként.
if(t->key_size == 14)
{
// uint8_t* key128 = calloc(16, sizeof(uint8_t));
// memcpy(key128, key, t->key_size);
<------>uint8_t key128[16];
key128[0] = key[0];
key128[1] = key[1];
key128[2] = key[2];
key128[3] = key[3];
key128[4] = key[4];
key128[5] = key[5];
key128[6] = key[6];
key128[7] = key[7];
key128[8] = key[8];
key128[9] = key[9];
key128[10] = key[10];
key128[11] = key[11];
key128[12] = key[12];
key128[13] = key[13];
key128[14] = 0;
key128[15] = 0;
uint8_t result;
int ret = rte_lpm6_lookup(ext->rte_table, key128, &result);
return ret == 0 ? ext->content[result] : t->default_val;
}
More information about the P4
mailing list