[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