Может ли кто-нибудь помочь мне переписать эту функцию (функцию doTheMath
) для выполнения вычислений на графическом процессоре? Я использовал несколько хороших дней, пытаясь окунуться в него, но никакого результата. Интересно, может быть, кто-нибудь может помочь мне переписать эту функцию так, как вам кажется, что это похоже на журнал, поскольку я даю тот же результат в конце. Я попытался использовать @jit
из numba
, но по какой-то причине он на самом деле намного медленнее, чем запуск кода, как обычно. С огромным размером выборки цель заключается в том, чтобы значительно сократить время выполнения, поэтому я считаю, что GPU - это самый быстрый способ сделать это.
Я немного объясню, что на самом деле происходит. Реальные данные, которые выглядят почти идентичными, как образцы данных, созданных в приведенном ниже коде, делятся на типовые размеры приблизительно 5.000.000 строк каждого образца или около 150 МБ на файл. Всего около 600.000.000 строк или 20 ГБ данных. Я должен прокручивать эти данные, образец по образцу, а затем строку за строкой в каждом примере, брать последние 2000 (или другие) строки по каждой строке и запускать функцию doTheMath
, которая возвращает результат. Затем этот результат сохраняется на жестком диске, где я могу сделать с ним другую работу. Как вы можете видеть ниже, мне не нужны все результаты всех строк, только те, которые больше определенной суммы. Если я запустил свою функцию, как сейчас, на python, я получаю около 62 секунд на 1.000.000 строк. Это очень долгое время, учитывая все данные и как быстро это сделать.
Я должен упомянуть, что я загружаю файл реальных данных по файлу в ОЗУ с помощью data = joblib.load(file)
, поэтому загрузка данных не является проблемой, так как занимает всего около 0,29 секунды на файл. После загрузки я запускаю весь код ниже. Наибольшее время занимает функция doTheMath
. Я готов отдать все свои 500 очков репутации, которые у меня есть на stackoverflow, в награду за кого-то, кто хочет помочь мне переписать этот простой код для запуска на GPU. Я заинтересован в GPU, я действительно хочу посмотреть, как это делается по этой проблеме.
EDIT/UPDATE 1:
Вот ссылка на небольшой образец реальных данных: data_csv.zip Около 102000 строк реальных данных1 и 2000 строк для реальных данных2a и data2b, Используйте minimumLimit = 400
для данных реальных образцов
EDIT/UPDATE 2: Ниже приведено краткое изложение ответов ниже. До сих пор у нас есть 4 ответа на исходное решение. Тот, который предлагает @Divakar, - это всего лишь хитрости к исходному коду. Из двух настроек только первая применима к этой проблеме, вторая - хорошая настройка, но здесь она не применяется. Из трех других ответов два из них - решения на основе процессоров, и один тензорный процессор GPU. Графический процессор Tensorflow от Paul Panzer кажется многообещающим, но когда я фактически запускаю его на графическом процессоре, он медленнее оригинала, поэтому код все еще нуждается в улучшении.
Другие два решения на базе процессора представлены @PaulPanzer (чистое решение numpy) и @MSeifert (решение numba). Оба решения дают очень хорошие результаты и обе технологические данные чрезвычайно быстрые по сравнению с исходным кодом. Из них один, представленный Полом Панцером, быстрее. Он обрабатывает около 1.000.000 строк за 3 секунды. Единственная проблема заключается в меньших размерах пакета, это можно преодолеть либо переключением на решение numba, предлагаемым MSeifert, либо даже исходным кодом после всех настроек, которые обсуждались ниже.
Я очень рад и благодарен @PaulPanzer и @MSeifert за работу, которую они сделали в своих ответах. Тем не менее, поскольку это вопрос о решении на базе GPU, я ожидаю, если кто-то захочет попробовать его в версии GPU и посмотреть, насколько быстрее данные будут обрабатываться на графическом процессоре по сравнению с текущим процессором решения. Если не будет других ответов, превосходящих чисто чистое решение @PaulPanzer, я приму его ответ как правильный и получаю награду:)
EDIT/UPDATE 3: @Divakar опубликовал новый ответ с решением для GPU. После моих тестов на реальных данных скорость даже не сравнима с решениями для сопоставления процессоров. Процессор GPU обрабатывает около 5.000.000 за 1,5 секунды. Это невероятно:) Я очень взволнован решением GPU, и я благодарю @Divakar за его публикацию. Также я благодарю @PaulPanzer и @MSeifert за их решения для процессоров:) Теперь мои исследования продолжаются с невероятной скоростью благодаря GPU:)
import pandas as pd
import numpy as np
import time
def doTheMath(tmpData1, data2a, data2b):
A = tmpData1[:, 0]
B = tmpData1[:,1]
C = tmpData1[:,2]
D = tmpData1[:,3]
Bmax = B.max()
Cmin = C.min()
dif = (Bmax - Cmin)
abcd = ((((A - Cmin) / dif) + ((B - Cmin) / dif) + ((C - Cmin) / dif) + ((D - Cmin) / dif)) / 4)
return np.where(((abcd <= data2a) & (abcd >= data2b)), 1, 0).sum()
#Declare variables
batchSize = 2000
sampleSize = 5000000
resultArray = []
minimumLimit = 490 #use 400 on the real sample data
#Create Random Sample Data
data1 = np.matrix(np.random.uniform(1, 100, (sampleSize + batchSize, 4)))
data2a = np.matrix(np.random.uniform(0, 1, (batchSize, 1))) #upper limit
data2b = np.matrix(np.random.uniform(0, 1, (batchSize, 1))) #lower limit
#approx. half of data2a will be smaller than data2b, but that is only in the sample data because it is randomly generated, NOT the real data. The real data2a is always higher than data2b.
#Loop through the data
t0 = time.time()
for rowNr in range(data1.shape[0]):
tmp_df = data1[rowNr:rowNr + batchSize] #rolling window
if(tmp_df.shape[0] == batchSize):
result = doTheMath(tmp_df, data2a, data2b)
if (result >= minimumLimit):
resultArray.append([rowNr , result])
print('Runtime:', time.time() - t0)
#Save data results
resultArray = np.array(resultArray)
print(resultArray[:,1].sum())
resultArray = pd.DataFrame({'index':resultArray[:,0], 'result':resultArray[:,1]})
resultArray.to_csv("Result Array.csv", sep=';')
Спецификации ПК, над которыми я работаю:
GTX970(4gb) video card;
i7-4790K CPU 4.00Ghz;
16GB RAM;
a SSD drive
running Windows 7;
Как побочный вопрос, поможет ли вторая видеоплата в SLI по этой проблеме?