En annan sak som hänt i dagarna är inte direkt relaterat till C++ och minnessäkerhet, men definitivt relaterat till flera saker som diskuterats i denna tråd runt vad som eventuellt gör C++ unikt.
Nvidia har precis lanserat stöd för att skriva CUDA-kernels i Python!
https://thenewstack.io/nvidia-finally-adds-native-python-supp...
https://developer.nvidia.com/cuda-python
En viktig orsak är att de ser stora begränsningar i hur pass populärt något kan bli idag om det bara finns till C och C++. Totala antalet programmerare växer fortfarande mycket snabbt, på senare tid är det Afrika, Sydamerika och Asien tillväxten är störst.
C och C++ är inte speciellt populärt i dessa grupper. Samtidigt växer Pythons popularitet väldigt snabbt, det har nu även passerat JS som mest använda språk på github (d.v.s. det är #1 där).
Så hur är det relevant här? Att skriva CUDA-kernels gör man primärt för att få upp prestanda rejält, något "vanliga" Python inte direkt är känt för att vara jätte bra på. Vidare kräver effektiv användning av GPU förståelse för "host memory", "global device memory", "shared memory" och "local memory". Det är något man behöver hantera explicit i CUDA och det är exponerat även i Python.
I just detta fall tror jag faktiskt det kan bli riktigt bra med Python. Vissa användningar av Python list-comprehension är en väldigt bra match i hur man vill jobba med GPGPU för att det ska bli effektiv. Och om det blir bra kan rätt mycket exakt samma teknik användas för att då kraftigt SIMD-optimera Python kod (GPUer är rätt mycket väldigt breda SIMD maskiner).
För att ta ett enkelt konkret exempel på hur en CUDA-kernel kan se ut
https://nyu-cds.github.io/python-numba/05-cuda/
from __future__ import division
from numba import cuda
import numpy
import math
# CUDA kernel
@cuda.jit
def add_one_kernel(io_array):
pos = cuda.grid(1)
if pos < io_array.size:
io_array[pos] += 1
# Host code
data = numpy.ones(256)
threadsperblock = 256
blockspergrid = math.ceil(data.shape[0] / threadsperblock)
# Launch kernel
add_one_kernel[blockspergrid, threadsperblock](data)
print(data)
Och detta är motsvarande "vanliga" CUDA, misstänker att det inte finns någon prestandaskillnad i GPGPU-kernel (PyTorch gör liknande saker "under huven" och ger extremt effektiva GPU-kernels trots att man skriver logiken i Python)
#include <stdio.h>
#include <cuda_runtime.h>
// CUDA kernel in C
__global__ void add_one_kernel(float *io_array, int size) {
int pos = blockIdx.x * blockDim.x + threadIdx.x;
if (pos < size) {
io_array[pos] += 1.0f;
}
}
int main() {
const int N = 256;
// Allocate host memory
size_t size = N * sizeof(float);
float *h_data = (float*)malloc(size);
for (int i = 0; i < N; ++i) {
h_data[i] = 1.0f;
}
// Allocate device memory and move from host to device
float *d_data;
cudaMalloc((void**)&d_data, size);
cudaMemcpy(d_data, h_data, size, cudaMemcpyHostToDevice);
int threadsPerBlock = 256;
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
// Launch kernel
add_one_kernel<<<blocksPerGrid, threadsPerBlock>>>(d_data, N);
cudaMemcpy(h_data, d_data, size, cudaMemcpyDeviceToHost);
// Print result
for (int i = 0; i < N; ++i) {
printf("%.1f ", h_data[i]);
}
printf("\n");
// Cleanup
cudaFree(d_data);
free(h_data);
return 0;
}