Finance: Black-Scholes

The Black-Scholes Equation estimates the price of a European option over time. The formula itself can be used in a number of ways, the most basic of which is to use the projected value to smartly hedge the option on its underlying asset. The simulation in this sample is vectorized with Intel® C++ autovectorization and parallelized with Intel Cilk™ cilk_for.

 

Code Change Highlights:

  • cilk_for
  • linear version: (black_scholes.cpp, black_scholes_serial())
    for(int i = 0; i<NUM_ITERATIONS; i++) { for(int option = 0; option<OPT_N; ++option) { float T = OptionYears[option]; float X = OptionStrike[option]; float S = StockPrice[option]; float sqrtT = sqrtf(T); float d1 = (logf(S / X) + (c_riskfree + c_half * c_volatility * c_volatility) * T) / (c_volatility * sqrtT); float d2 = d1 - c_volatility * sqrtT; #ifdef _WIN32 float CNDD1 = CND(d1); float CNDD2 = CND(d2); #else float CNDD1 = c_half + c_half*erff(SQRT1_2*d1); float CNDD2 = c_half + c_half*erff(SQRT1_2*d2); #endif float expRT = expf(-c_riskfree * T); CallResult[option] = S * CNDD1 - X * expRT * CNDD2; PutResult[option] = CallResult[option] + expRT - S; } }
    cilk_for version: (black_scholes.cpp, black_scholes_cilk())
    cilk_for(int i = 0; i<NUM_ITERATIONS; i++) { cilk_for(int option = 0; option<OPT_N; ++option) { float T = OptionYears[option]; float X = OptionStrike[option]; float S = StockPrice[option]; float sqrtT = sqrtf(T); float d1 = (logf(S / X) + (c_riskfree + c_half * c_volatility * c_volatility) * T) / (c_volatility * sqrtT); float d2 = d1 - c_volatility * sqrtT; #ifdef _WIN32 float CNDD1 = CND(d1); float CNDD2 = CND(d2); #else float CNDD1 = c_half + c_half*erff(SQRT1_2*d1); float CNDD2 = c_half + c_half*erff(SQRT1_2*d2); #endif float expRT = expf(-c_riskfree * T); CallResult[option] = S * CNDD1 - X * expRT * CNDD2; PutResult[option] = CallResult[option] + expRT - S; } }

Performance Data:

Note: Modified Speedup shows performance speedup with respect to serial implementation.

Modified Speedup Compiler (Intel® 64) Compiler options System specifications
cilk_for: 3.39x Intel C++ Compiler 15.0 for Windows /O3 /Oi /fp:fast /QxHost /Qipo Microsoft Windows Server 2012* (x64)
2rd generation Intel® Xeon® E3 1280 CPU @ 3.50GHz
8GB memory
cilk_for: 5.8x Intel C++ Compiler 15.0 for Linux -O3 -fp-model fast -xHost -ipo RHEL 7 (x64)
4rd Generation Intel Core™ i7-4790 CPU @ 3.60GHz
32GB memory

Build Instructions:

  • For Microsoft Visual Studio* 2010 and 2012 users:
  • Open the solution .sln file
    [Optional] To collect performance numbers (will run example 5 times and take average time):
    • Project Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions: add PERF_NUM
    Choose a configuration (for best performance, choose a release configuration):
    • Intel-debug and Intel-release: uses Intel® C++ compiler
    • VSC-debug and VSC-release: uses Visual C++ compiler (only linear/scalar will run)
  • For Windows* Command Line users:
  • Enable your particular compiler environment
    for Intel® C++ Compiler:
    • Open the appropriate Intel C++ compiler command prompt
    • Navigate to project folder
    • Compile with Build.bat [perf_num]
      • perf_num: collect performance numbers (will run example 5 times and take average time)
    • To run: Build.bat run [help|0|1|2|3|4]
    For Visual C++ Compiler (only linear/scalar will run):
    • Open the appropriate MicrosoftVisual Studio* 2010 or 2012 command prompt
    • Navigate to project folder
    • To compile: Build.bat [perf_num]
      • perf_num: collect performance numbers (will run example 5 times and take average time)
    • To run: Build.bat run
  • For Linux* or OS X* users:
  • From a terminal window, navigate to the project folder
    Using Intel C++ compiler:
    • Set the icc environment: source <icc-install-dir>/bin/compilervars.sh {ia32|intel64}
    • To compile: make [icpc] [perf_num=1]
      • perf_num=1: collect performance numbers (will run example 5 times and take average time)
    • To run: make run [option=help|0|1|2|3|4]
    Using gcc (only linear/scalar will run):
    • To compile: make gcc [perf_num=1]
      • perf_num=1: collect performance numbers (will run example 5 times and take average time)
    • To run: make run
Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.