Пост навеян полемикой с коллегой околорыночником-инфоцыганом который путается в матчасти и доказывает что чёрное это белое и наоборот. Начало и контекст тут — «smart-lab.ru/blog/1264570.php»(надеюсь не удалит свой пост или мои комменты там)
В кратце опишу суть. Коллега утверждал что его библиотека на си шарп быстрее всего что есть на сегодняшний момент
… для супер скоростных вычислений, которой сейчас нет равных...
и даже быстрей чем GPU. Долго пытался съехать с темы, переобувался и менял свои же изначально предложенные тесты но даже после этого всё равно был уделан(отцом) причём не признает это даже после того как я тут выложу код который может запустить любой желающий и проверить на своём железе. Как видеокарта(у меня старая(есть новая но лежит в упаковке т.к. пока не сильно нужна) уделывает цпу в десятки тысяч раз на его задаче(которую он перефразировал от изначальной но картину это сильно не поменяло)). Ну теперь к цифрам пришлось самому тестами заниматься. Цифры такие
запуск на 200 000 000(200 млн)(условных опционах(условных потому что реализовано просто для того чтобы показать разницу в производительности а не корректность расчётов))
CPU — 14136,905 ms (14.1 M/s)
GPU kernel — 0.237 ms (842545 M/s))
GPU E2E — 986 ms (202.8 M/s)
Speedup kernel 59554.9x(!!! (для ясности)это значит ускорение в 59 000 раз !!!!!!!!!!!!!!!)
на 100 000 000
CPU — 7043,103 ms (14.2 M/s)
GPU kernel — 0.226 ms (442509 M/s))
GPU E2E — 487 ms (205 M/s)
Speedup kernel 31169.0x
на 1 000 000
CPU — 72.463 ms (13.8 M/s)
GPU kernel — 0.234 ms (4280.2 M/s))
GPU E2E — 487 ms (173 M/s)
Speedup kernel 310.0x
на 100 000
CPU — 9.934 ms (10.1 M/s)
GPU kernel — 0.196 ms (511 M/s))
GPU E2E — 0.802 ms (124 M/s)
Speedup kernel 50.8x
на 1000
CPU — 0.64 ms (15.6 M/s)
GPU kernel — 0.196 ms (6.9 M/s))
GPU E2E — 0.063 ms (15.8 M/s)
Speedup kernel 0.4x
и только когда размер батча 1000 гпу проигрывает. И это архитектура паскаль т.е. GTX а не RTX(и не тем более новые которые сейчас актуальны) видеокарта(с быстрой памятью, тензорными ядрами и т.п. без оптимизаций и т.п. просто код как есть от гпт(мой и лень писать и нет смысла для меня)) т.е. тезисы инфоцыгана никак не подтвердились а наоборот как я и говорил при достаточной загрузке с точки зрения вычислений и кол-ва данных для этих вычислений цпу кратно отстаёт и даже не в 500-1000 раз а в десятки тысяч раз например с вариантом 100 млн. отрыв в 31000 раз с 200 000 000 в 59 000 раз. Именно об этом я и говорил на протяжении всей полемики но коллега не очень видимо готов принять реальность и предпочитает жить в своём уютном выдуманном мире. Вот код
/////////////////
#include <cuda_runtime.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>static void cpu_bs(float *S, float *K, float *T, float *r, float *v, float *d, float *ve, int n) {
for (int i = 0; i < n; i++) {
float d1 = (logf(S[i]/K[i]) + (r[i] + v[i]*v[i]*0.5f)*T[i]) / (v[i]*sqrtf(T[i]));
d[i] = 0.5f*(1.0f + erf(d1/sqrtf(2.0f)));
ve[i] = S[i]*sqrtf(T[i])*(0.39894228f*expf(-0.5f*d1*d1));
}
}__global__ void gpu_bs(float *S, float *K, float *T, float *r, float *v, float *d, float *ve, int n) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i >= n) return;
float d1 = (logf(S[i]/K[i]) + (r[i] + v[i]*v[i]*0.5f)*T[i]) / (v[i]*sqrtf(T[i]));
d[i] = 0.5f*(1.0f + erf(d1/sqrtf(2.0f)));
ve[i] = S[i]*sqrtf(T[i])*(0.39894228f*expf(-0.5f*d1*d1));
}int main() {
const int N = 200000000;
srand(time(0));
float *hS, *hK, *hT, *hr, *hv, *hd, *hve, *hdg, *hveg;
float *dS, *dK, *dT, *dr, *dv, *dd, *dve;
size_t sz = N * sizeof(float);
hS = (float*)malloc(sz); hK = (float*)malloc(sz); hT = (float*)malloc(sz);
hr = (float*)malloc(sz); hv = (float*)malloc(sz);
hd = (float*)malloc(sz); hve = (float*)malloc(sz);
hdg = (float*)malloc(sz); hveg = (float*)malloc(sz);
for (int i = 0; i < N; i++) {
hS[i] = 80 + rand()%70; hK[i] = 90 + rand()%40;
hT[i] = 0.1f + (rand()%100)/365.0f;
hr[i] = 0.03f + (rand()%20)/1000.0f;
hv[i] = 0.15f + (rand()%30)/100.0f;
}
clock_t t1 = clock();
cpu_bs(hS, hK, hT, hr, hv, hd, hve, N);
clock_t t2 = clock();
float cpu_t = (float)(t2-t1)*1000/CLOCKS_PER_SEC;
printf(«CPU: %.3f ms (%.1f M/s)\n», cpu_t, N/cpu_t/1000);
cudaMalloc(&dS, sz); cudaMalloc(&dK, sz); cudaMalloc(&dT, sz);
cudaMalloc(&dr, sz); cudaMalloc(&dv, sz); cudaMalloc(&dd, sz); cudaMalloc(&dve, sz);
cudaMemcpy(dS, hS, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dK, hK, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dT, hT, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dr, hr, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dv, hv, sz, cudaMemcpyHostToDevice);
cudaEvent_t evs, eve;
cudaEventCreate(&evs); cudaEventCreate(&eve);
cudaEventRecord(evs);
gpu_bs<<<64, 1024>>>(dS, dK, dT, dr, dv, dd, dve, N);
cudaEventRecord(eve); cudaDeviceSynchronize();
float ker_t; cudaEventElapsedTime(&ker_t, evs, eve);
cudaMemcpy(hdg, dd, sz, cudaMemcpyDeviceToHost);
cudaMemcpy(hveg, dve, sz, cudaMemcpyDeviceToHost);
cudaEventRecord(evs);
cudaMemcpy(dS, hS, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dK, hK, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dT, hT, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dr, hr, sz, cudaMemcpyHostToDevice);
cudaMemcpy(dv, hv, sz, cudaMemcpyHostToDevice);
gpu_bs<<<64, 1024>>>(dS, dK, dT, dr, dv, dd, dve, N);
cudaDeviceSynchronize();
cudaMemcpy(hdg, dd, sz, cudaMemcpyDeviceToHost);
cudaMemcpy(hveg, dve, sz, cudaMemcpyDeviceToHost);
cudaEventRecord(eve); cudaEventSynchronize(eve);
float e2e_t; cudaEventElapsedTime(&e2e_t, evs, eve);
printf(«GPU kernel: %.3f ms (%.1f M/s)\n», ker_t, N/ker_t/1000);
printf(«GPU E2E: %.3f ms (%.1f M/s)\n», e2e_t, N/e2e_t/1000);
printf(«Speedup: kernel %.1fx, E2E %.1fx\n», cpu_t/ker_t, cpu_t/e2e_t);
cudaFree(dS); cudaFree(dK); cudaFree(dT); cudaFree(dr); cudaFree(dv); cudaFree(dd); cudaFree(dve);
free(hS); free(hK); free(hT); free(hr); free(hv); free(hd); free(hve); free(hdg); free(hveg);
return 0;
}
/////////////////
любой желающий может проверить запустив у себя на железе цифры будут отличаться от моих т.к. нужно конкретно такое железо как у меня но динамика будет одинакова как только растёт кол-во данных и вычислений то цпу начинает получать знатной «звизды»(условно выражаясь). Поэтому коллеги кому интересно берём не стесняемся никаких заумных методологических словоблудий только факты(как отец умеет). Этот бенчмарк это как раз именно то что коллега просил реализовать т.е. он слился от своего начального предложения(т.к. и там он тоже сильно проигрывает) но и тут как можно увидеть(запустив код) как гпу за 300 долларов рвёт в клочья всю билиберду которую он пытается впарить и писать что — … для супер скоростных вычислений, которой сейчас нет равных… и целый день мой потратил на бесполезный спор о неоспариваемом. Хотел написать целый пост но лень да и не нужно теперь т.к. цифры говорят всё сами за себя.
Потому коллеги которые будут покупать его софт за тысячи долларов сначала оцените насколько оно Вам надо т.к. очень много заблуждений в его посылах и не удивлюсь если качество того что не имеет отношения к скорости будет на том же уровне. Т.е. кто-то заплатит этому околорыночнику-инфоцыгану за его поделку а она не то что пользы не принесёт(это ещё полбеды) она ещё насчитает не то что декларировалось и то что моделировалось(в плане рисков, хвостов и т.д. и т.п.) будет только его фантазией и неправильными расчётами а это довольно опасная тема т.к. может ушатать Ваш портфель который он принялся моделировать. Выше конкретный пример его некомпетенции он относится к скорости и техническим моментам(в которых он видимо не в теме) но не исключаю что тоже самое будет и при заявленой функциональности его поделки. Поэтому хорошо сначала подумайте перед тем как покупать или использовать его софт.
Ещё раз таблица от гпт(т.к. самому лень такое делать(цифры на моём железе а оформил гпт))
| N опционов | CPU (M/s) | GPU E2E (M/s) | GPU kernel vs CPU | E2E vs CPU |
|---------------|-----------|---------------|-------------------|------------|
| 1 000 | 15.6 | 15.8 | 0.4x | НИЧЬЯ |
| 100 000 | 10.1 | 124 | 50x | ✅ 12x |
| 1 000 000 | 13.8 | 173 | 310x | ✅ 12.5x |
| 100 000 000| 14.2 | 205 | 31 000x | ✅ 14.5x |
| 200 000 000| 14.1 | 202 | 59 000x | ✅ 14x |
Если упростить и понять о чём был спор у нас целый день это о том что в колонке GPU kernel vs CPU(это говорил я) а он всё пытался доказать что E2E vs CPU(GPU E2E (M/s)) работает медленее(т.е. с передачей данных от хоста(процессора) на видеокарту и обратно) на гпу чем на процессоре но как видно из таблицы даже в этом моменте гпу быстрей в 14 раз. Хотя это не типичная для него задача т.к. ему надо много данных и вычислений на борт латентность доступа к данным в этом случае будет околонулевая за счёт того что очень много того что можно считать пока данные «едут на базу»(что в случае с процессором недостижимо) но это не суть можно так глубоко не вникать.
Он опять напишет что реализовано не верно и не так и не то считается да это так и я не заморачивался с этим т.к. это и не важно как я писал в начале т.к. мы смотрим только то насколько как и когда гпу ушатывает цпу и тут это видно идеально. Если всё сделать корректно то будет ровно тоже самое только изменится время и цифры но суть останется та же а она в том что цпу это детский сад если сравнивать в задачах где важна вычислительная мощность. Его комментарий(который я предвижу) о том что не нужно столько считать т.к. нет столько опционов и т.д. и т.п. не бъётся с его же собственным коментарием
...2️⃣ Throughput: 1 млн опционов за 41 мс — почему это важно
Ты говорил:«Никому не нужно считать триллионы опционов каждый тик».
Абсолютно верно.
Но 1 млн опционов за 41 мс — это не про «триллионы».
Это про:✅ Бэктестинг многолетней истории по тысячам инструментов
✅ Риск-метрики по крупному портфелю в реальном времени
✅ Монте-Карло с миллионами симуляций...
В общем совсем запутался коллега и заврался и при этом всё равно проиграл дискуссию под чистую(даже в части трансфера данных от хоста к гпу т.е. даже с этой темой гпу ушатывает цпу). Даже переобуваясь и отказываясь от своих же предложенных мне бенчмарков. На сайте nvidia где-то видел то ли про библиотеки то ли примеры кода по вычислению всяких блэкшоулзов и т.п. тем. Лень этим заниматься т.к. сути это не меняет и будет ровно тоже самое при корректной реализации(идеальной с точки зрения корректности и производительности т.к. nvidia ботвы не впарит). Поэтому продолжать эту эпопею не вижу смысла всё доказано инфоцыган наказан, софт обесценен(в части скорости что неверно заявлялось им как факт, проверить может любой желающий(код выше)). Всё на месяц или несколько наверное мне хватит не писать(а так хотелось бы и вовсе завязать) но не уверен уже что такое возможно для меня.