νΉν μΌλ ¨μ ifβ¦ else ifλ¬Έμ΄ μκ³ κ° λ¬Έμ΄ νκ° ν μλ νλ₯ μ 미리 μκ³ trueμλ€λ©΄ νλ₯ μμλλ‘ μ λ ¬νλ λ° μ€ν μκ°μ μ°¨μ΄κ° μΌλ§λλ©λκΉ? μλ₯Ό λ€μ΄, μ΄κ²μ μ νΈν΄μΌν©λκΉ?
if (highly_likely)
//do something
else if (somewhat_likely)
//do something
else if (unlikely)
//do something
μ΄μ?:
if (unlikely)
//do something
else if (somewhat_likely)
//do something
else if (highly_likely)
//do something
μ λ ¬ λ λ²μ μ΄ λ λΉ λ₯Ό κ² κ°μ§λ§, κ°λ μ±μ΄λ λΆμμ©μ μ‘΄μ¬λ₯Ό μν΄ μ΅μ νλμ§ μμ μμλ‘ μ£Όλ¬Έν μ μμ΅λλ€. μ€μ λ‘ μ½λλ₯Ό μ€νν λκΉμ§ CPUκ° λΆκΈ° μμΈ‘μ μΌλ§λ μ μννλμ§ λ§νκΈ°λ μ΄λ ΅μ΅λλ€.
λ°λΌμ μ΄κ²μ μ€ννλ κ³Όμ μμ νΉμ μ¬λ‘μ λν λ΄ μμ μ μ§λ¬Έμ λλ΅νμ§λ§ λ€λ₯Έ μ견 / ν΅μ°°λ ₯λ λ£κ³ μΆμ΅λλ€.
μ€μ :μ΄ μ§λ¬Έμ ifνλ‘κ·Έλ¨ λμμ λ€λ₯Έ μν₯μμ£Όμ§ μμΌλ©΄ μ λ¬Έμ μμλ‘ μ¬μ λ ¬ ν μ μλ€κ³ κ°μ ν©λλ€ . λ΄ λλ΅μ λ°λ₯΄λ©΄, μΈ κ°μ§ μ‘°κ±΄λΆ ν
μ€νΈλ μνΈ λ°°νμ μ΄λ©° λΆμμ©μ΄ μμ΅λλ€. λΆλͺ
ν, μνλ νλμ λ¬μ±νκΈ° μν΄ μ§μ μ μΌμ ν μμλ‘ νκ°ν΄μΌνλ€λ©΄ ν¨μ¨μ± λ¬Έμ λ λ¬Έμ κ°λλ€.
λ΅λ³
μΌλ°μ μΌλ‘ λͺ¨λ μΈν CPUκ° ν¬μλ λΈλμΉλ₯Ό μ²μ λ³Ό λ μ¬μ©νμ§ μλ κ²μΌλ‘ κ°μ£Όνλ κ²μ μλλλ€. Godboltμ μμ μ μ°Έμ‘°νμμμ€ .
κ·Έ ν, λΈλμΉλ λΈλμΉ μμΈ‘ μΊμλ‘ λ€μ΄κ°κ³ , κ³Όκ±°μ λΈλμΉλ μμΈ‘μ μ리기 μν΄ μ¬μ©λ©λλ€.
λ°λΌμ κΈ΄λ°ν 루νμμ μλͺ»λ μμμ μν₯μ μλμ μΌλ‘ μμ΅λλ€. λΈλμΉ μμΈ‘κΈ°λ μ΄λ€ λΈλμΉ μΈνΈκ° κ°μ₯ κ°λ₯μ±μ΄ λμμ§ μκ² λ κ²μ΄λ©° 루νμμ μ¬μν μμ μμ μ μννλ©΄ μμ μ°¨μ΄κ° ν¬κ² μ¦κ°νμ§ μμ΅λλ€.
μΌλ°μ μΌλ‘ λλΆλΆμ μ»΄νμΌλ¬λ κΈ°λ³Έμ μΌλ‘ (λ€λ₯Έ μ΄μ κ° μμ) μμ± λ λ¨Έμ μ½λλ₯Ό μ½λμμ μ£Όλ¬Έν λ°©μκ³Ό κ±°μ λμΌνκ² μ£Όλ¬Έν©λλ€. λ°λΌμ λ¬Έμ΄ μ€ν¨ ν λ μ λ°©ν₯ λΆκΈ° μΈ κ²½μ°.
λ°λΌμ β첫 λ²μ§Έ λ§λ¨βμμ μ΅μμ λΆκΈ° μμΈ‘μ μ»μ κ°λ₯μ±μ μ€μ΄λ μμλ‘ λΆκΈ°λ₯Ό μ£Όλ¬Έν΄μΌν©λλ€.
μΌλ ¨μ 쑰건μ κ±Έμ³ μ¬λ¬ λ² λ¨λ¨ν λ°λ³΅λκ³ μ¬μν μμ μ μννλ λ§μ΄ν¬λ‘ λ²€μΉ λ§ν¬λ λͺ λ Ή μ λ±μ μμ μν₯μΌλ‘ μΈν΄ μλμ λΆκΈ° μμΈ‘ λ¬Έμ μλ κ±°μ μν₯μ λ―ΈμΉμ§ μμ΅λλ€. λ°λΌμμ΄ κ²½μ° κ²½ν λ²μΉμ΄ μ λ’°ν μ μμΌλ―λ‘λ₯Ό νλ‘νμΌ λ§ν΄μΌν©λλ€ .
λν 벑ν°ν λ° κΈ°ν μ¬λ¬ μ΅μ νκ° μμ νμ΄νΈ 루νμ μ μ©λ©λλ€.
λ°λΌμ μΌλ°μ μΈ μ½λμμ κ°μ₯ κ°λ₯μ±μ΄ λμ μ½λλ₯Ό ifλΈλ‘ λ΄μ λ£μΌλ©΄ μΊμλμ§ μμ λΆκΈ° μμΈ‘ λλ½μ΄ μ΅μνλ©λλ€. κ½ μ‘°μ΄λ κ²½μ° μΌλ° κ·μΉμ λ°λΌ μμνμμμ€. λ λ§μ μ λ³΄κ° νμνλ©΄ νλ‘νμΌ λ§ μ΄μΈμ μ νμ κ±°μ μμ΅λλ€.
μΌλΆ ν μ€νΈκ° λ€λ₯Έ ν μ€νΈλ³΄λ€ ν¨μ¬ μ λ ΄νλ©΄ λΉμ°νμ΄ λͺ¨λ κ²μ΄ μ°½ λ°μΌλ‘ λμ΅λλ€.
λ΅λ³
λλ λ κ°μ§ λ€λ₯Έ ifβ¦ else ifλΈλ‘ μ μ€ν μκ°μ μ νκΈ° μν΄ λ€μ ν
μ€νΈλ₯Ό ꡬμ±νμ΅λλ€. νλλ νλ₯ μμλ‘ μ λ ¬λκ³ λ€λ₯Έ νλλ μμμΌλ‘ μ λ ¬λμμ΅λλ€.
#include <chrono>
#include <iostream>
#include <random>
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;
int main()
{
long long sortedTime = 0;
long long reverseTime = 0;
for (int n = 0; n != 500; ++n)
{
//Generate a vector of 5000 random integers from 1 to 100
random_device rnd_device;
mt19937 rnd_engine(rnd_device());
uniform_int_distribution<int> rnd_dist(1, 100);
auto gen = std::bind(rnd_dist, rnd_engine);
vector<int> rand_vec(5000);
generate(begin(rand_vec), end(rand_vec), gen);
volatile int nLow, nMid, nHigh;
chrono::time_point<chrono::high_resolution_clock> start, end;
//Sort the conditional statements in order of increasing likelyhood
nLow = nMid = nHigh = 0;
start = chrono::high_resolution_clock::now();
for (int& i : rand_vec) {
if (i >= 95) ++nHigh; //Least likely branch
else if (i < 20) ++nLow;
else if (i >= 20 && i < 95) ++nMid; //Most likely branch
}
end = chrono::high_resolution_clock::now();
reverseTime += chrono::duration_cast<chrono::nanoseconds>(end-start).count();
//Sort the conditional statements in order of decreasing likelyhood
nLow = nMid = nHigh = 0;
start = chrono::high_resolution_clock::now();
for (int& i : rand_vec) {
if (i >= 20 && i < 95) ++nMid; //Most likely branch
else if (i < 20) ++nLow;
else if (i >= 95) ++nHigh; //Least likely branch
}
end = chrono::high_resolution_clock::now();
sortedTime += chrono::duration_cast<chrono::nanoseconds>(end-start).count();
}
cout << "Percentage difference: " << 100 * (double(reverseTime) - double(sortedTime)) / double(sortedTime) << endl << endl;
}
/ O2μ ν¨κ» MSVC2017μ μ¬μ©νλ©΄ μ λ ¬ λ λ²μ μ΄ μ λ ¬λμ§ μμ λ²μ λ³΄λ€ μΌκ΄λκ² μ½ 28 % λΉ λ¦ λλ€. luk32μ μ견μ λ°λΌ, λλ λν λ ν μ€νΈμ μμλ₯Ό λ°κΎΈμ΄ λμ λλ μ°¨μ΄λ₯Ό λ§λλλ€ (22 % λ 28 %). μ΄ μ½λλ Intel Xeon E5-2697 v2μ Windows 7μμ μ€νλμμ΅λλ€. μ΄κ²μ λ¬Όλ‘ λ¬Έμ μ λ°λΌ λ€λ₯΄λ©° κ²°μ μ μΈ λ΅λ³μΌλ‘ ν΄μλμ΄μλ μλ©λλ€.
λ΅λ³
λμ μμ€ν μ΄ μ€μ λ‘ μν₯μλ°λ κ²μ΄ νμ€νμ§ μμΌλ©΄ μλ©λλ€. κΈ°λ³Έμ μΌλ‘ κ°λ μ±μ΄ μ’μ΅λλ€.
λλ λΉμ μ κ²°κ³Όλ₯Ό μμ¬ν©λλ€. μμ λ₯Ό μ½κ° μμ νμΌλ―λ‘ μ€νμ μ·¨μνλ κ²μ΄ λ μ½μ΅λλ€. μ€νλ € Ideone μ μμμ΄ λΉ λ₯΄μ§ λ§ μΌκ΄μ±μκ² λ³΄μ¬μ€λλ€. νΉμ λ¬λ¦¬κΈ°μμλ λλλ‘ λ€μ§μ΄μ§λλ€. κ²°κ³Όκ° κ²°μ μ μ΄μ§ μλ€κ³ λ§νκ³ μΆμ΅λλ€. μ½λ¦¬ 루 λ μ€μ μ°¨μ΄λλ³΄κ³ νμ§ μμ΅λλ€. λμ€μ λ΄ odroid xu4μμ Exynos5422 CPUλ₯Ό νμΈν μ μμ΅λλ€.
νλ CPUμλ λΆκΈ° μμΈ‘κΈ°κ° μμ΅λλ€. λ°μ΄ν°μ λͺ λ Ήμ΄λ₯Ό λͺ¨λ ν리 νμΉ (pre-fetch)νκΈ°μν λ§μ λ‘μ§μ΄ μμΌλ©°, μ΅μ x86 CPUλ λ€μ λλν©λλ€. ARM λλ GPUμ κ°μ μΌλΆ μ¬λ¦Ό μν€ν μ²λμ΄ μ·¨μ½μ μ μ·¨μ½ ν μ μμ΅λλ€. κ·Έλ¬λ μ€μ λ‘ μ»΄νμΌλ¬μ λμ μμ€ν μ ν¬κ² μμ‘΄ν©λλ€.
μ§μ μμ μ΅μ νλ λ§€μ° μ·¨μ½νκ³ μμμ μ΄λΌκ³ λ§ν μ μμ΅λλ€. μ λ§ λ―ΈμΈ μ‘°μ λ¨κ³λ‘λ§ μννμμμ€.
μνΈ:
#include <chrono>
#include <iostream>
#include <random>
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;
int main()
{
//Generate a vector of random integers from 1 to 100
random_device rnd_device;
mt19937 rnd_engine(rnd_device());
uniform_int_distribution<int> rnd_dist(1, 100);
auto gen = std::bind(rnd_dist, rnd_engine);
vector<int> rand_vec(5000);
generate(begin(rand_vec), end(rand_vec), gen);
volatile int nLow, nMid, nHigh;
//Count the number of values in each of three different ranges
//Run the test a few times
for (int n = 0; n != 10; ++n) {
//Run the test again, but now sort the conditional statements in reverse-order of likelyhood
{
nLow = nMid = nHigh = 0;
auto start = chrono::high_resolution_clock::now();
for (int& i : rand_vec) {
if (i >= 95) ++nHigh; //Least likely branch
else if (i < 20) ++nLow;
else if (i >= 20 && i < 95) ++nMid; //Most likely branch
}
auto end = chrono::high_resolution_clock::now();
cout << "Reverse-sorted: \t" << chrono::duration_cast<chrono::nanoseconds>(end-start).count() << "ns" << endl;
}
{
//Sort the conditional statements in order of likelyhood
nLow = nMid = nHigh = 0;
auto start = chrono::high_resolution_clock::now();
for (int& i : rand_vec) {
if (i >= 20 && i < 95) ++nMid; //Most likely branch
else if (i < 20) ++nLow;
else if (i >= 95) ++nHigh; //Least likely branch
}
auto end = chrono::high_resolution_clock::now();
cout << "Sorted:\t\t\t" << chrono::duration_cast<chrono::nanoseconds>(end-start).count() << "ns" << endl;
}
cout << endl;
}
}
λ΅λ³
κ·Έλ₯ λ΄ 5 μΌνΈ. μ§μ μ΄ λ€μμ μμ‘΄ν΄μΌνλ κ²½μ° μ£Όλ¬Έμ ν¨κ³Όκ°μλ κ² κ°μ΅λλ€.
-
κ° if λ¬Έμ κ°λ₯μ±
-
λΆκΈ° μμΈ‘μκ° μμν μμλ λ°λ³΅ νμμ λλ€.
-
μ½λ ννΈμ κ°μ μ»΄νμΌλ¬ ννΈ
μ΄λ¬ν μμλ₯Ό νμνκΈ° μν΄ λ€μ κΈ°λ₯μ λ²€μΉλ§νΉνμ΅λλ€.
ordered_ifs ()
for (i = 0; i < data_sz * 1024; i++) {
if (data[i] < check_point) // highly likely
s += 3;
else if (data[i] > check_point) // samewhat likely
s += 2;
else if (data[i] == check_point) // very unlikely
s += 1;
}
reversed_ifs ()
for (i = 0; i < data_sz * 1024; i++) {
if (data[i] == check_point) // very unlikely
s += 1;
else if (data[i] > check_point) // samewhat likely
s += 2;
else if (data[i] < check_point) // highly likely
s += 3;
}
ordered_ifs_with_hints ()
for (i = 0; i < data_sz * 1024; i++) {
if (likely(data[i] < check_point)) // highly likely
s += 3;
else if (data[i] > check_point) // samewhat likely
s += 2;
else if (unlikely(data[i] == check_point)) // very unlikely
s += 1;
}
reversed_ifs_with_hints ()
for (i = 0; i < data_sz * 1024; i++) {
if (unlikely(data[i] == check_point)) // very unlikely
s += 1;
else if (data[i] > check_point) // samewhat likely
s += 2;
else if (likely(data[i] < check_point)) // highly likely
s += 3;
}
λ°μ΄ν°
λ°μ΄ν° λ°°μ΄μ 0μμ 100 μ¬μ΄μ λμλ₯Ό ν¬ν¨ν©λλ€.
const int RANGE_MAX = 100;
uint8_t data[DATA_MAX * 1024];
static void data_init(int data_sz)
{
int i;
srand(0);
for (i = 0; i < data_sz * 1024; i++)
data[i] = rand() % RANGE_MAX;
}
κ²°κ³Ό
λ€μ κ²°κ³Όλ Intel i5 @ 3,2 GHz λ° G ++ 6.3.0μ λν κ²μ λλ€. 첫 λ²μ§Έ μΈμλ check_point (μ¦, κ°λ₯μ±μ΄ λμ if λ¬Έμ κ²½μ° %% νλ₯ )μ΄κ³ λ λ²μ§Έ μΈμλ data_sz (μ : λ°λ³΅ νμ)μ λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/50/4 4660 ns 4658 ns 150948
ordered_ifs/50/8 25636 ns 25635 ns 27852
ordered_ifs/75/4 4326 ns 4325 ns 162613
ordered_ifs/75/8 18242 ns 18242 ns 37931
ordered_ifs/100/4 1673 ns 1673 ns 417073
ordered_ifs/100/8 3381 ns 3381 ns 207612
reversed_ifs/50/4 5342 ns 5341 ns 126800
reversed_ifs/50/8 26050 ns 26050 ns 26894
reversed_ifs/75/4 3616 ns 3616 ns 193130
reversed_ifs/75/8 15697 ns 15696 ns 44618
reversed_ifs/100/4 3738 ns 3738 ns 188087
reversed_ifs/100/8 7476 ns 7476 ns 93752
ordered_ifs_with_hints/50/4 5551 ns 5551 ns 125160
ordered_ifs_with_hints/50/8 23191 ns 23190 ns 30028
ordered_ifs_with_hints/75/4 3165 ns 3165 ns 218492
ordered_ifs_with_hints/75/8 13785 ns 13785 ns 50574
ordered_ifs_with_hints/100/4 1575 ns 1575 ns 437687
ordered_ifs_with_hints/100/8 3130 ns 3130 ns 221205
reversed_ifs_with_hints/50/4 6573 ns 6572 ns 105629
reversed_ifs_with_hints/50/8 27351 ns 27351 ns 25568
reversed_ifs_with_hints/75/4 3537 ns 3537 ns 197470
reversed_ifs_with_hints/75/8 16130 ns 16130 ns 43279
reversed_ifs_with_hints/100/4 3737 ns 3737 ns 187583
reversed_ifs_with_hints/100/8 7446 ns 7446 ns 93782
λΆμ
1. μ£Όλ¬Έμ΄ μ€μνλ€
4K λ°λ³΅κ³Ό (κ±°μ) 100 % νλ₯ λ‘ μ νΈλκ° λμ μ§μ μ κ²½μ° κ·Έ μ°¨μ΄λ 223 %μ λ¬ν©λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/100/4 1673 ns 1673 ns 417073
reversed_ifs/100/4 3738 ns 3738 ns 188087
4K λ°λ³΅ λ° μ νΈλκ° λμ 50 % νλ₯ μ κ²½μ° μ°¨μ΄λ μ½ 14 %μ λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/50/4 4660 ns 4658 ns 150948
reversed_ifs/50/4 5342 ns 5341 ns 126800
2. λ°λ³΅ νμκ° μ€μ
λ§€μ° μ’μνλ μ§μ μ (κ±°μ) 100 % νλ₯ μ λν 4Kμ 8K λ°λ³΅μ μ°¨μ΄λ (μμλλ‘) μ½ 2 λ°°μ λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/100/4 1673 ns 1673 ns 417073
ordered_ifs/100/8 3381 ns 3381 ns 207612
κ·Έλ¬λ μ νΈλκ° λμ λ¬Έμ₯μ 50 % νλ₯ μ λν 4Kμ 8K λ°λ³΅μ μ°¨μ΄λ 5,5 λ°°μ λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/50/4 4660 ns 4658 ns 150948
ordered_ifs/50/8 25636 ns 25635 ns 27852
μ κ·Έλ μ΅λκΉ? λΆκΈ° μμΈ‘ λ³μκ° λλ½λμμ΅λλ€. μμμ μΈκΈ ν κ° μ¬λ‘μ λν λΆκΈ° λλ½μ΄ μμ΅λλ€.
ordered_ifs/100/4 0.01% of branch-misses
ordered_ifs/100/8 0.01% of branch-misses
ordered_ifs/50/4 3.18% of branch-misses
ordered_ifs/50/8 15.22% of branch-misses
λ°λΌμ i5μμ λΈλμΉ μμΈ‘κΈ°λ κ·Έλ κ² ν¬μ§ μμ λΈλμΉ λ° λκ·λͺ¨ λ°μ΄ν° μΈνΈμ λν΄ λλλλ‘ μ€ν¨ν©λλ€.
ννΈ ννΈ
4K λ°λ³΅μ κ²½μ° κ²°κ³Όλ 50 % νλ₯ μμλ λ€μ λμκ³ 100 % νλ₯ μ λν΄μλ λ€μ λμμ§λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/50/4 4660 ns 4658 ns 150948
ordered_ifs/100/4 1673 ns 1673 ns 417073
ordered_ifs_with_hints/50/4 5551 ns 5551 ns 125160
ordered_ifs_with_hints/100/4 1575 ns 1575 ns 437687
κ·Έλ¬λ 8K λ°λ³΅μ κ²½μ° κ²°κ³Όκ° νμ μ‘°κΈ λ μ’μ΅λλ€.
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
ordered_ifs/50/8 25636 ns 25635 ns 27852
ordered_ifs/100/8 3381 ns 3381 ns 207612
ordered_ifs_with_hints/50/8 23191 ns 23190 ns 30028
ordered_ifs_with_hints/100/8 3130 ns 3130 ns 221205
λ°λΌμ ννΈλ λμμ΄λμ§λ§ μ‘°κΈλ§ λμμ΄λ©λλ€.
κ²°λ‘ μ νμ μ½λλ₯Ό λ²€μΉλ§νΉνλ€λ κ²μ λλ€. κ²°κ³Όλ λλΌ μΈ μ μμ΅λλ€.
ν¬λ§μ΄ λμμ΄λ©λλ€.
λ΅λ³
μ μΌν μ§μ§ λ΅μ΄ κ°μ΄ μ¬κΈ°μ λ€λ₯Έ λͺ κ°μ§ λ΅λ³μ λ°νμΌλ‘, κ·Έκ²μ λ³Έλ€ : κ·Έκ²μ μμ‘΄νλ€ . κ·Έκ²μ μ μ΄λ λ€μμ λ¬λ € μμ΅λλ€ (κ·Έλ¬λμ΄ μμλλ‘ μ€μνμ§λ μμ§λ§).
- κ° μ§μ μ μλ νλ₯ . μ΄κ²μ μλ μ§λ¬Έμ λλ€. κΈ°μ‘΄μ λ΅λ³μ λ°νμΌλ‘ νλ₯ μμΌλ‘ μ λ ¬νλ λ° λμμ΄λλ λͺ κ°μ§ 쑰건μ΄μλ κ²μ²λΌ 보μ΄μ§λ§ νμ κ·Έλ μ§λ μμ΅λλ€. μλ νλ₯ μ΄ ν¬κ² λ€λ₯΄μ§ μμ κ²½μ° μμκ° μ΄λ€ μμλ‘λ μ°¨μ΄κ° λμ§ μμ μ μμ΅λλ€. κ·Έλ¬λ 첫 λ²μ§Έ μ‘°κ±΄μ΄ 99.999 %μ μκ°μ λ°μνκ³ λ€μ μ‘°κ±΄μ΄ λ¨μ κ²μ μΌλΆμΈ κ²½μ°μλ κ°μ₯ κ°λ₯μ±μ΄ λμ κ²μ λ¨Όμ λ°°μΉνλ κ²μ΄ νμ΄λ° μΈ‘λ©΄μμ μ 리νλ€κ³ κ°μ ν©λλ€.
- κ° λΈλμΉμ λν μ°Έ / κ±°μ§ μ‘°κ±΄ κ³μ° λΉμ©. 쑰건μ ν μ€νΈνλ λ° λλ μκ° λΉμ©μ΄ ν μ§μ μμ λ€λ₯Έ μ§μ μ λΉν΄ μ€μ λ‘ λμ κ²½μ° μ΄λ νμ΄λ°κ³Ό ν¨μ¨μ±μ ν° μν₯μ μ€ μ μμ΅λλ€. μλ₯Ό λ€μ΄, κ³μ°νλ λ° 1 μκ° λ¨μ (μ : λΆμΈ λ³μμ μν νμΈ)κ° κ±Έλ¦¬λ 쑰건과 κ³μ°νλ λ° μμ, μλ°±, μμ² λλ μ¬μ§μ΄ μλ°±λ§ μκ° λ¨μκ° νμν λ€λ₯Έ 쑰건 (μ : λμ€ν¬μμ νμΌ λλ λκ·λͺ¨ λ°μ΄ν°λ² μ΄μ€μ λν 볡μ‘ν SQL 쿼리 μν). μ½λκ° λ§€λ² μμλλ‘ μ‘°κ±΄μ νμΈνλ€κ³ κ°μ νλ©΄ λ λΉ λ₯Έ μ‘°κ±΄μ΄ λ¨Όμ λμ΄μΌν©λλ€ (λ¨Όμ μ€ν¨ν λ€λ₯Έ 쑰건μ μ’ μλμ§ μλ ν).
- μ»΄νμΌλ¬ / μΈν°νλ¦¬ν° μΌλΆ μ»΄νμΌλ¬ (λλ μΈν°ν리ν°)μλ μ±λ₯μ μν₯μ μ€ μμλ λ€λ₯Έ μ’ λ₯μ μ΅μ νκ° ν¬ν¨λ μ μμ΅λλ€ (μΌλΆ μ΅μ μ μ»΄νμΌ λ° / λλ μ€ν μ€μ νΉμ μ΅μ μ μ νν κ²½μ°μλ§ λνλ¨). λ°λΌμ λμΌν λΆκΈ°λ₯Ό μ νν λμΌν μ»΄νμΌλ¬λ₯Ό μ¬μ©νμ¬ λμΌν μμ€ν μμ λ κ°μ μ»΄νμΌ λ° λ¬λ¦¬ λμΌν μ½λμ μ€νμ λ²€μΉλ§νΉνμ§ μλ ν μ μΌν μ°¨μ΄μ μ μ»΄νμΌλ¬ λ³νμ λν μ½κ°μ μ¬μ λ₯Ό μ£Όμ΄μΌν©λλ€.
- μ΄μ 체μ / νλμ¨μ΄ luk32 λ° Yakkμμ μΈκΈνλ―μ΄ λ€μν CPUμλ μ΄μ 체μ μ λ§μ°¬κ°μ§λ‘ μ체 μ΅μ ν κΈ°λ₯μ΄ μμ΅λλ€. λ°λΌμ λ²€μΉ λ§ν¬λ μ¬κΈ°μλ λ³νλκΈ° μ½μ΅λλ€.
- μ½λ λΈλ‘ μ€ν λΉλ λΆκΈ°λ₯Ό ν¬ν¨νλ λΈλ‘μ κ±°μ μ‘μΈμ€νμ§ μλ κ²½μ° (μ : μμ μ€ ν λ²λ§) λΆκΈ°λ₯Ό λ°°μΉνλ μμλ κ±°μ μ€μνμ§ μμ΅λλ€. λ€λ₯Έ ννΈμΌλ‘, μ½λμ μ€μν λΆλΆμμ μ½λκ°μ΄ μ½λ λΈλ‘μ λ§μΉλ κ²½μ° λ²€μΉ λ§ν¬μ λ°λΌ μμκ° μ€μ ν μ μμ΅λλ€.
νμ€νκ² μ μμλ μ μΌν λ°©λ²μ μ½λλ₯Ό μ΅μ’ μ μΌλ‘ μ€νν μλ λ μμ€ν κ³Ό λμΌνκ±°λ λ§€μ° μ μ¬ν μμ€ν μμ νΉμ μ¬λ‘λ₯Ό λ²€μΉλ§νΉνλ κ²μ λλ€. νλμ¨μ΄, μ΄μ 체μ λ±μ΄ λ€λ₯Έ λ€μν μμ€ν μμ μ€ννλ €λ κ²½μ° μ¬λ¬ λ³νμ λ²€μΉ λ§ν¬νμ¬ μ΄λ κ²μ΄ κ°μ₯ μ ν©ν μ§ νμΈνλ κ²μ΄ μ’μ΅λλ€. ν μ νμ μμ€ν μμλ νλμ μμλ‘, λ€λ₯Έ μ νμ μμ€ν μμλ λ€λ₯Έ μμλ‘ μ½λλ₯Ό μ»΄νμΌνλ κ²μ΄ μ’μ΅λλ€.
λ΄ κ°μΈμ μΈ κ²½ν κ·μΉ (λλΆλΆμ κ²½μ° λ²€μΉ λ§ν¬κ°μλ κ²½μ°)μ λ€μμ κΈ°μ€μΌλ‘ μ£Όλ¬Έν΄μΌν©λλ€.
- μ΄μ 쑰건μ κ²°κ³Όμ μμ‘΄νλ 쑰건
- 쑰건 κ³μ° λΉμ©
- κ° μ§μ μ μλ νλ₯ .
λ΅λ³
νμκ° μΌλ°μ μΌλ‘ κ³ μ±λ₯ μ½λμ λν΄μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ²μ κ°μ₯ μ½κΈ° μ¬μ΄ μμλ₯Ό μ μ§νμ§λ§ μ»΄νμΌλ¬μ ννΈλ₯Ό μ 곡νλ κ²μ λλ€. λ€μμ Linux 컀λμ ν μμ λλ€ .
if (likely(access_ok(VERIFY_READ, from, n))) {
kasan_check_write(to, n);
res = raw_copy_from_user(to, from, n);
}
if (unlikely(res))
memset(to + (n - res), 0, res);
μ¬κΈ°μλ μ‘μΈμ€ νμΈμ΄ ν΅κ³Όλκ³ μ μ€λ₯κ° λ°νλμ§ μλλ€κ³ κ°μ resν©λλ€. μ΄λ¬ν if μ μ€ νλλ₯Ό μ¬μ λ ¬νλ €κ³ νλ©΄ μ½λκ° νΌλ λ μ μμ§λ§, λ§€ν¬λ‘ likely()μ unlikely()λ§€ν¬λ‘λ μ€μ λ‘ μ μμ μΈ κ²½μ°μ μμΈλ 무μμΈμ§ μ§μ ν¨μΌλ‘μ¨ κ°λ
μ±μ ν₯μμν΅λλ€.
μ΄λ¬ν λ§€ν¬λ‘μ Linux ꡬνμ GCC νΉμ κΈ°λ₯μ μ¬μ© ν©λλ€ . clangκ³Ό Intel C μ»΄νμΌλ¬λ λμΌν ꡬ문μ μ§μνλ κ²μΌλ‘ 보μ΄μ§λ§ MSVCμλ κ·Έλ¬ν κΈ°λ₯μ΄ μμ΅λλ€ .
λ΅λ³
λν μ»΄νμΌλ¬μ μ»΄νμΌνλ νλ«νΌμ λ°λΌ λ€λ¦ λλ€.
μ΄λ‘ μ μΌλ‘ κ°μ₯ κ°λ₯μ±μ΄ λμ 쑰건μ μ μ΄ μ νλ₯Ό κ°λ₯ν ν μ κ²ν΄μΌν©λλ€.
μΌλ°μ μΌλ‘ κ°μ₯ κ°λ₯μ±μ΄ λμ 쑰건μ λ€μκ³Ό κ°μ΅λλ€.
if (most_likely) {
// most likely instructions
} else β¦
κ°μ₯ μΈκΈ°μλ asmμ conditionμ΄ true μΌ λ μ ννλ μ‘°κ±΄λΆ λΆκΈ°λ₯Ό κΈ°λ°μΌλ‘ ν©λλ€ . κ·Έ C μ½λλ λ€μκ³Ό κ°μ μμ¬ asmμΌλ‘ λ³ν λ κ²μ λλ€.
jump to ELSE if not(most_likely)
// most likely instructions
jump to end
ELSE:
β¦
μ΄κ²μ μ νκ° CPUκ° μ€ν νμ΄ν λΌμΈμ μ·¨μνκ³ νλ‘κ·Έλ¨ μΉ΄μ΄ν°κ° λ³κ²½ λμκΈ° λλ¬Έμ μ€λ¨λκΈ° λλ¬Έμ λλ€ (μ€μ λ‘λ νμ΄ν λΌμΈμ μ§μνλ μν€ν μ²μ κ²½μ°). κ·Έλ° λ€μ μ»΄νμΌλ¬μ κ΄ν κ²μΈλ°, μ΄λ 컨νΈλ‘€μ΄ λ μ ννλλ‘ ν΅κ³μ μΌλ‘ κ°μ₯ κ°λ₯μ±μ΄ λμ 쑰건μ κ°λ κ²μ λν μ κ΅ν μ΅μ νλ₯Ό μ μ©νκ±°λ μ μ©νμ§ μμ μ μμ΅λλ€.