Может кто-нибудь помочь мне переписать эту функцию (функция doTheMath
) выполнить вычисления на графическом процессоре? Я использовал несколько хороших дней, пытаясь окунуться в него, но никакого результата. Интересно, может быть, кто-нибудь может помочь мне переписать эту функцию так, как вам кажется, что это похоже на журнал, поскольку я даю тот же результат в конце. Я пытался использовать @jit
от numba
, но по какой-то причине он на самом деле намного медленнее, чем запуск кода, как обычно. С огромным размером выборки цель заключается в том, чтобы значительно сократить время выполнения, поэтому я считаю, что GPU - это самый быстрый способ сделать это.Python: переписать циклическую математическую функцию numpy для работы на 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, я действительно хочу посмотреть, как это делается по этой проблеме.
РЕДАКТИРОВАТЬ/ОБНОВЛЕНИЕ 1: Вот ссылка на небольшую выборку реальных данных: data_csv.zip О 102000 рядов реальной data1 и 2000 строк для реальной data2a и data2b. Используйте minimumLimit = 400
на данных реального образца
EDIT/UPDATE 2: Для тех, кто следит этот пост здесь краткое резюме ниже ответов. До сих пор у нас есть 4 ответа на исходное решение. Тот, который предлагает @Divakar, - это всего лишь хитрости к исходному коду. Из двух настроек только первая применима к этой проблеме, вторая - хорошая настройка, но здесь она не применяется. Из трех других ответов два из них - решения на основе процессоров, и один тензорный процессор GPU. Tensorflow-GPU от Paul Panzer кажется многообещающим, но когда я фактически запускаю его на GPU, он медленнее оригинала, поэтому код все еще нуждается в улучшении.
Другие два решения на базе процессоров представлены @PaulPanzer (чистое решение numpy) и @MSeifert (решение numba). Оба решения дают очень хорошие результаты и обе технологические данные чрезвычайно быстрые по сравнению с исходным кодом. Из них один, представленный Полом Панцером, быстрее. Он обрабатывает около 1.000.000 строк за 3 секунды. Единственная проблема заключается в меньших размерах пакета, это можно преодолеть либо переключением на решение numba, предлагаемое MSeifert, либо даже исходным кодом после всех настроек, которые обсуждались ниже.
Я очень доволен и благодарен @PaulPanzer и @MSeifert за то, что они сделали на их ответах. Тем не менее, поскольку это вопрос о решении на базе GPU, я ожидаю, если кто-то захочет попробовать его в версии GPU и посмотреть, насколько быстрее данные будут обрабатываться на графическом процессоре по сравнению с текущим процессором решения.Если не будет никаких других ответов превосходит показатели @ чистого раствора Numpy PaulPanzer в то я приму его ответ как правого и получает награду :)
EDIT/UPDATE 3: @Divakar опубликовал новый ответ с решение для графического процессора. После моих тестов на реальных данных скорость даже не сравнима с решениями для сопоставления процессоров. Процессор GPU обрабатывает около 5.000.000 за 1,5 секунды. Это невероятно :) Я очень взволнован решением GPU, и я благодарю @Divakar за его публикацию. Как и я благодарю @PaulPanzer и @MSeifert для их решения CPU :) Теперь мое исследование продолжается с невероятной скоростью из-за ГПУ :)
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 по этой проблеме?
SLI не имеет значения и не имеет ничего общего с CUDA. Что касается того, как вы можете преобразовать этот код - вы делаете это, садясь перед своим компьютером и вводите новый код ядра CUDA на свой компьютер. И если вы хотите запустить его на двух графических процессорах, вы также вводите код API для управления запуском кода на двух графических процессорах. – talonmies
Вы всегда можете попробовать [numba] (http://numba.pydata.org/), который может * попробовать * автоматически использовать CUDA в некоторой степени. Лучшим подходом было бы использовать графики вычислений Theano/Tensorflow и реализовать алгоритм в их рамках для его компиляции для графических процессоров. Но да, в общем, это о том, чтобы знать CUDA и разрабатывать для вас свой алгоритм, используя доступные инструменты, такие как упоминаемые вами когти. – sascha
Благодарим вас за предложение @sascha. Я думал, что Theano и Tensorflow предназначены только для проблем машинного обучения. Я увижу в numba на данный момент – RaduS